LoginSignup
0
0

More than 1 year has passed since last update.

Ruby初心者が「TryRuby」で引っかかったところ

Last updated at Posted at 2022-05-26

概要

はじめまして,今回新しくRubyを学習するにあたって,Rubyの雰囲気を感じ取るため,WEBブラウザ上でRubyに触れることができるTryRubyをやってみました.初心者の私が「ん?」ってなったところをピックアップして何がわからなかったか, 紹介したいと思います.初心者にRubyを教えるにあたってここに引っかかりやすいかもという参考になれば幸いです.
私もいつか教える側になったときにはこれを読み返してこの部分は丁寧に教えたいですね.

メソッドのあとの「 ! 」?

保存してしまい込みました
ticket = [12, 47, 35]
ticket.sort!
puts ticket
# [12, 35, 47]

リストを整列(sort)しました。変数ticketはもう変わっています。 sort!メソッドのさいごに、大きく目立つ感嘆符があるのに気づきましたか? Rubyのメソッドは、しばしば変数の中身を変更してしまう時にこのように叫びます。 ですがこれは何てことはない、ただの印です。
-TryRuby: 保存してしまい込みました

よくある「これは呪文です」パターンですね.少し実験してみましょう.

「sort!」
ticket = [12, 47, 35]
ticket.sort!
puts ticket
# [12, 35, 47]
「sort」
ticket = [12, 47, 35]
ticket.sort
puts ticket
# [12, 47, 35]

「!」がついたメソッドではもとの変数が書き換えられていますね.
更に調べて見ると

defで関数を定義したときに「def letterCange!(str)」のように関数名の末尾に「!」をつけることがあります。これは、関数の処理の中で破壊的メソッドを行っていることをわかりやすくするためのものです。このため、関数名に「!」があろうが、なかろうが実行される処理自体は変わりません。
【Rails・Ruby】メソッド名や関数名の末尾の!(ビックリマーク)と?(はてなマーク)の意味は何かを実例で解説

(追記)Ruby のメソッド名の ! の有無は破壊的/非破壊的を意味する,わけじゃない - Qiita
タイトル通りですが,メソッドの後の「!」に関して誤解したまま次に進まぬよう上記記事も参照すると良いです.
@scivola様ありがとうございます.

「!」がついているかどうかによってsortメソッドの動作が変わるわけではなく初めからsortメソッドとsort!メソッドの2つが存在しているということですね.Rubyのリファレンスマニュアルを見るとたしかにそれぞれのメソッドが定義されています.

変数のあとの「:」?

ちっちゃな空っぽの本&一口書評をもうちょっと
books = {}
books["Gravitys Rainbow"] = :splendid
books["The deep end"]  = :abysmal
books["Living colors"] = :mediocre
puts books
puts books.length
# {"Gravitys Rainbow"=>"splendid", "The deep end"=>"abysmal", "Living colors"=>"mediocre"}
# 3

何だこれは・・・?

これらの評価は文字列ではありません。単語の前にコロンをつけると、それはシンボルになります。 シンボルとは、コンピュータメモリの観点で、文字列よりもコストの安いものになります。 もしプログラムの中で繰り返し繰り返し同じ単語を使いっていたら、シンボルを使うべきです。 その単語の数千のコピーをメモリ上に持つのではなく、コンピュータは一度だけシンボルを格納します。
-TryRuby: 一口書評をもうちょっと

文字列では宣言されるたびに文字列の領域が生成されるのに対して、
シンボルは1度生成されるとポインタとなり、複数回使用しても同じ領域で使用される。
-【Ruby】シンボル

これはシンボルというらしく,これを使うと「:splended」がいくつあってもメモリ上は一つしかなくて余計なメモリ喰わないということのようです.

文字列ではないと言う割に

ruby
some_symbol = :symbol
puts some_symbol.reverse
# lobmys

のように文字列みたいにreverseできたのが不思議です.ドキュメント見てもSymbolクラスにReverseメソッド見当たらない...

some_symbol = :symbol
puts symbol.reverse!
#<anonymous>': String#reverse! not supported. Mutable String methods are not supported in Opal. (NotImplementedError)
#	from <anonymous>'
#	from <anonymous>'
#	from <anonymous>:19:38:in `eval'
#	from <anonymous>:1:6:in `eval'

こうするとちゃんと怒られるから,文字列が持つ一部のメソッドは使えるようにしているということなのでしょうか???

(↓↓↓ココから追記↓↓↓)
TryRubyの「30分ありますか? 今すぐRubyを試しましょう!」ではデフォルトでOpalというRubyをJavascriptに変換するコンパイラが使用されていてそのせいのようです.
TryRubyのPlaygroundCRubyを選択すると

ruby
some_symbol = symbol:
puts some_symbol.reverse

# (file): eval:2:in `<main>': undefined method `reverse' for :symbol:Symbol (NoMethodError)
# (Exception)


このようにsymbolクラスにはreverseメソッドがありません!とちゃんと怒られます.
@scivola様,教えてただきありがとうございます.
(↑↑↑追記ココまで↑↑↑)

「|」で囲まれた変数!?

辛辣な書評をつけてしまった?
books = {}
books["Gravitys Rainbow"] = :splendid
books["The deep end"]  = :abysmal
books["Living colors"] = :mediocre

ratings = Hash.new {0}
books.values.each { |rate|
  ratings[rate] += 1
}
puts ratings
# {"splendid"=>1, "abysmal"=>1, "mediocre"=>2}

このrateはどっから出てきたんだ・・・って思いました.しかし進めてみると.

数え上げる
5.times { print "Odelay! " }

# Odelay! Odelay! Odelay! Odelay! Odelay!

たったいま使った、驚くべき新しい道具はブロックです。 ~・・・~ 基本的に、ブロックとは中かっこでくくられたRubyのコード片のことです。
TryRuby: 数え上げる

ここでいう{print "Odelay! }"がブロックであるというわけですね.

今はいくつ?
5.times { |time|
  puts time
}
# 0
# 1
# 2
# 3
# 4

ブロックを使った最初の例(評価をカウントしたプログラムです)で見たように、ブロックには値を渡すことができます。 どんな値が渡されるかは、ブロックを実行するメソッドによって決定されます。
ブロックが受け取った値は、ブロックのはじめ、二つのパイプ文字(|)の間にある変数に置かれます。
TryRuby: 今はいくつ

つまりメソッドが吐き出した値を||で囲んだ変数が受け取るということですね.
(追記)||で囲った変数は「ブロックパラメーター」と言うそうです.@scivola様に教えていただきました.ありがとうございます

これなら以前に見たことがあります.JavaScriptのコールバック関数としてアロー関数を入れたときの書き方に似ていると思いました.

javascript
someArray = [0, 1, 2, 3, 4];

someArray.forEach(value => {
  console.log(value);
});

書き方がなんとなく似ていますよね?valueforeachが取り出した配列の要素が入り,アロー関数の中身でconsole.logされています.
厳密にいうとJavascriptはforeachメソッドがコールバック関数を受け取っているということだったと思うので,内部での処理は異なるのでしょうね.

配列に向かう「<<」?

あなた自身の芝
class Blurbalizer
    def initialize(title)
      @title  = title
      @blurbs = [] # A fresh clean array
                   # for storing Blurbs
    end
  
    def add_a_blurb(mood, content)
      # The << means add to the end of the array
      @blurbs << Blurb.new(mood, content)
    end
  
    def show_timeline
      puts "Blurbify: #{@title} has #{@blurbs.count} Blurbs"
  
      @blurbs.sort_by { |t|
        t.time
      }.reverse.each { |t|
        puts "#{t.content.ljust(40)} #{t.time}"
      }
    end
  end
  
  myapp = Blurbalizer.new "The Big Blurb"

コードの中のコメントに答え書いてありましたが,<<は配列の最後に要素を追加する演算子のようです.

感想

今まで経験のあるPythonやJavascriptとまた違った書き方の特徴があったため敬遠していましたが,実際に触ってみるとなんのことはありませんでした.もう少し書いてみないとRubyの良さが十分にわかっていませんが,この後はRuby on RailsでWEBアプリを作ってみようと思っているので,少しずつその辺も見えてくるでしょう.

最後に,なにか間違いのご指摘やご意見がありましたら,コメントをお願いします.
特になかった人はRubyの好きなところや初心者時代に引っかかったところを教えてくださると嬉しいです!

0
0
9

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0