概要
はじめまして,今回新しくRubyを学習するにあたって,Rubyの雰囲気を感じ取るため,WEBブラウザ上でRubyに触れることができるTryRubyをやってみました.初心者の私が「ん?」ってなったところをピックアップして何がわからなかったか, 紹介したいと思います.初心者にRubyを教えるにあたってここに引っかかりやすいかもという参考になれば幸いです.
私もいつか教える側になったときにはこれを読み返してこの部分は丁寧に教えたいですね.
メソッドのあとの「 ! 」?
ticket = [12, 47, 35]
ticket.sort!
puts ticket
# [12, 35, 47]
リストを整列(sort)しました。変数ticketはもう変わっています。 sort!メソッドのさいごに、大きく目立つ感嘆符があるのに気づきましたか? Rubyのメソッドは、しばしば変数の中身を変更してしまう時にこのように叫びます。 ですがこれは何てことはない、ただの印です。
-TryRuby: 保存してしまい込みました
よくある「これは呪文です」パターンですね.少し実験してみましょう.
ticket = [12, 47, 35]
ticket.sort!
puts ticket
# [12, 35, 47]
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」がいくつあってもメモリ上は一つしかなくて余計なメモリ喰わないということのようです.
文字列ではないと言う割に
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のPlaygroundでCRuby
を選択すると
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のコールバック関数としてアロー関数を入れたときの書き方に似ていると思いました.
someArray = [0, 1, 2, 3, 4];
someArray.forEach(value => {
console.log(value);
});
書き方がなんとなく似ていますよね?value
にforeach
が取り出した配列の要素が入り,アロー関数の中身で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の好きなところや初心者時代に引っかかったところを教えてくださると嬉しいです!