Rubyを使うといっても、本ブログではそこまで本格的にということではなく、あくまでもコマンドラインでパイプをつなげて組み立てるrubyコマンドとして使います。
Ruby インストール
インストールは、apt-get install ruby等で。
takk@deb9:~$ ruby --version ruby 2.3.3p222 (2016-11-21) [x86_64-linux-gnu] takk@deb9:~$
私の環境ではバージョン2.3.3でした。
Rubyで私が一番好きなところは、さくっと試せるってところです。
インタラクティブモードを備えてます。irbコマンドを実行するだけです。
takk@deb9:~$ irb irb(main):001:0> では、Hello Worldです。 irb(main):001:0> print "Hello World!" Hello World!=> nil irb(main):002:0>
はい。表示されましたね。
Hello World!と表示されたのは良いのですが、それに続く、nilとは何でしょうか。
ここで関数(メソッド)を定義してみましょう。関数を作るには、def 名称で始めて、endで終わります。
空関数を作ってみます
irb(main):002:0> def aaa() irb(main):003:1> end => :aaa irb(main):004:0>
aaaという名前を付けました。これを実行してみます。
irb(main):004:0> aaa => nil irb(main):005:0>
=> に続いてnilが表示されました。
次にaaaに戻り値を設定して実行してみます。
irb(main):005:0> def aaa() irb(main):006:1> return "HELLO" irb(main):007:1> end => :aaa irb(main):008:0> aaa => "HELLO" irb(main):009:0>
=> に続いてaaaの戻り値として設定した”HELLO”が表示されました。
先ほど戻り値を設定していなかった関数aaaでは、nilが表示されました。つまりnilとは何も値を戻してないってことです。
冒頭の表示はHello World!に改行がなくわかりづらかったのですが、改行を入れるとこうなります。
irb(main):009:0> print "Hello World!\n" Hello World! => nil irb(main):010:0>
実行後の一行目ではHello World!という表示結果、それに続いてnilが表示されていますね。つまり、printの戻り値です。
irbを抜けるには、quitを実行します。
irb(main):010:0> quit takk@deb9:~$
Ruby 変数
Perlの変数(スカラー)は頭に$がついてました。Rubyの変数も同じように$をつけることができます。Perlでは$はスカラー変数を表していましたが、Rubyではグローバル変数を表します。ローカル変数の場合は、$をつけません。
takk@deb9:~$ irb irb(main):001:0> $a="GLOBAL" => "GLOBAL" irb(main):002:0> b="local" => "local" irb(main):003:0> def aaa() irb(main):004:1> puts $a irb(main):005:1> puts b irb(main):006:1> end => :aaa irb(main):007:0> aaa GLOBAL NameError: undefined local variable or method `b' for main:Object from (irb):5:in `aaa' from (irb):7 from /usr/bin/irb:11:in `<main>' irb(main):008:0>
このように、$aはグローバル変数なので、aaaの中で参照できますが、bは、ローカル変数のため、aaa内から参照できません。
コマンドラインで使う分には、ほとんどローカル変数で事足りますので、$をつけないことになります。$がないと変数名が短くなるわけですので特な気がしますが、Perlでやっていたこんな表現ができなくなります。
takk@deb9:~$ perl -e '$a="HELLO"; print "$a $a\n"' HELLO HELLO takk@deb9:~$
Rubyで同じことをすると、当然なんですが文字列がそのまま表示されます。
takk@deb9:~$ ruby -e 'a="HELLO"; print "a a\n"' a a takk@deb9:~$
変数の中身を表示するには、こう書くことになります。
takk@deb9:~$ ruby -e 'a="HELLO"; puts a+" "+a' HELLO HELLO takk@deb9:~$
Rubyの変数は、インスタンス、クラス変数がありますが、コマンドラインで使う予定がないので覚えてません。Rubyはオブジェクト指向ですので、変数もオブジェクトです。
takk@deb9:~$ irb irb(main):001:0> a="123" => "123" irb(main):002:0>
今、文字列”123″をaに格納しました。aに1を足してみます。
irb(main):002:0> a + 1 TypeError: no implicit conversion of Fixnum into String from (irb):2:in `+' from (irb):2 from /usr/bin/irb:11:in `<main>' irb(main):003:0>
エラーになりました。文字列に数値の1を足したので当然ですね。Perlの方が特殊なのかもしれません。
aを数値として解釈するには、数値に変換するメソッドを使えばよいです。
irb(main):003:0> a.to_i + 1 => 124 irb(main):004:0>
頼もしいですね。オブジェクトなので、メソッドを使えば何でもできる気がしますね。
Ruby 配列
Ruby続きです。配列は、全体を[]で囲って要素を,(カンマ)で区切れば作成できます。
irb(main):001:0> a = [10,20,30,40] => [10, 20, 30, 40] irb(main):002:0>
要素へアクセスするには、0始まりのインデックスを指定します。
irb(main):002:0> a[3] => 40 irb(main):003:0>
クォートで囲まれた要素であれば、文字列の配列となります。
irb(main):003:0> a = ["aaa","bbb","ccc","ddd"] => ["aaa", "bbb", "ccc", "ddd"] irb(main):004:0> a[1] => "bbb" irb(main):005:0>
配列の各要素には、数値でも文字列でもその他オブジェクトも格納できます。
irb(main):005:0> a = [1,"aaa",2,"bbb"] => [1, "aaa", 2, "bbb"] irb(main):006:0> a[0] => 1 irb(main):007:0> a[1] => "aaa" irb(main):008:0>
文字列の配列を作成するときに、クォートが面倒なら、%wが使えます。
irb(main):008:0> a = %w(aaa bbb ccc ddd eee) => ["aaa", "bbb", "ccc", "ddd", "eee"] irb(main):009:0> a[3] => "ddd" irb(main):010:0>
Perlと同じく空白を含む文字列を要素にできません。
要素のサイズを取得するには、sizeメソッドを使います。
irb(main):010:0> a.size => 5 irb(main):011:0>
配列から配列を取り出したいなら、スライスが使えます。
インデックスを指定して範囲取得するなら、.(ピリオド)を使い、変数名[インデックス..インデックス]、と指定します。(…でも可)
irb(main):011:0> a[1..3] => ["bbb", "ccc", "ddd"] irb(main):012:0>
インデックスと、取得する要素数を指定する場合は、変数名[インデックス,要素数]と指定します。
irb(main):012:0> a[1,3] => ["bbb", "ccc", "ddd"] irb(main):013:0> a[1,4] => ["bbb", "ccc", "ddd", "eee"] irb(main):014:0>
Ruby 連想配列
Rubyの連想配列もPerlと同じくハッシュと呼ばれます。定義するには{}で囲んで、キーと値を書きます。
takk@deb9:~$ irb irb(main):001:0> a = {'dog' => '犬', irb(main):002:1* 'cat' => '猫', irb(main):003:1* 'fox' => '狐'} => {"dog"=>"犬", "cat"=>"猫", "fox"=>"狐"} irb(main):004:0> a['cat'] => "猫" irb(main):005:0>
数値もキーでできます。
irb(main):001:0> a = {10 => '犬', irb(main):002:1* 20 => '猫', irb(main):003:1* 30 => '狐'} => {10=>"犬", 20=>"猫", 30=>"狐"} irb(main):004:0> a[20] => "猫" irb(main):005:0>
文字列や数値だけではなく、Rubyのハッシュではシンボルが使えます。:から始める名称はシンボルとなります。
irb(main):001:0> a = {:dog => '犬', irb(main):002:1* :cat => '猫', irb(main):003:1* :fox => '狐'} => {:dog=>"犬", :cat=>"猫", :fox=>"狐"} irb(main):004:0> a[:fox] => "狐" irb(main):005:0>
Perlの連想配列の定義は,
%変数名=( キー => 値, …)
で、参照するのは、
$変数名{キー}
でしたが、Perlと比べてRubyの方が分かりやすい気がします。連想配列なんだから、配列と同じアクセス方法って覚えやすいですし。
Rubyのシンボルが使える点に関しては、Perlでは文字列のクォートが省略できますので、Perlの方が短く書けるのではないでしょうか。
takk@deb9:~$ perl -e '%a=(dog=>"犬",cat=>"猫"); print "$a{cat}\n"' 猫 takk@deb9:~$
Perlでは=>は,にできるので、偶数個の配列をハッシュにするなんてこともできますね。
takk@deb9:~$ perl -e '@array=1..6;print "@array\n"; %hash = @array; print "$hash{3}\n"' 1 2 3 4 5 6 4 takk@deb9:~$
Ruby 読み込み
Rubyのテキスト読み込みです。
例のごとく読み込むファイルを作成します。
takk@deb9:~$ seq 25 | pr -t5J | tee sample.txt 1 6 11 16 21 2 7 12 17 22 3 8 13 18 23 4 9 14 19 24 5 10 15 20 25 takk@deb9:~$
openとgetsを使って読み込みしてみます。getsメソッドで一行だけ読み込んで表示するだけのスクリプトです。
takk@deb9:~$ cat read.rb f=open("sample.txt") line = f.gets print line f.close()
実行するとsample.txtの先頭の一行だけ表示されます。
takk@deb9:~$ ruby read.rb 1 6 11 16 21 takk@deb9:~$
繰り返し読み込んで全部表示するには、whileを使います。どの言語も似たようなものですね。
takk@deb9:~$ cat read.rb f=open("sample.txt") while line = f.gets print line end f.close()
実行結果です。
takk@deb9:~$ ruby read.rb 1 6 11 16 21 2 7 12 17 22 3 8 13 18 23 4 9 14 19 24 5 10 15 20 25 takk@deb9:~$
File.readで全行を一括で読み込めます。
takk@deb9:~$ cat read.rb lines=File.read("sample.txt") print lines takk@deb9:~$ ruby read.rb 1 6 11 16 21 2 7 12 17 22 3 8 13 18 23 4 9 14 19 24 5 10 15 20 25 takk@deb9:~$
標準入力は$stdinで読めます。
takk@deb9:~$ seq 10 | ruby -e 'while line=$stdin.gets;print line;end' 1 2 3 4 5 6 7 8 9 10 takk@deb9:~$
しかもgetsの場合は、$stdinから読み込むのがデフォルトなので省略できます。
takk@deb9:~$ seq 10 | ruby -e 'while line=gets;print line;end' 1 2 3 4 5 6 7 8 9 10 takk@deb9:~$
Ruby 書き込み
読み込みはこんな感じでした。
takk@deb9:~$ cat read.rb f=open("in.txt") print f.gets f.close() takk@deb9:~$ ruby read.rb HELLO takk@deb9:~$
書き込みは読み込みの反対なのだから、もしかしてputs使うだけでは? と思い、やってみるとエラーになります。
takk@deb9:~$ cat write.rb f=open("out.txt") f.puts("HELLO") f.close() takk@deb9:~$ ruby write.rb write-ng.rb:2:in `write': not opened for writing (IOError) from write-ng.rb:2:in `puts' from write-ng.rb:2:in `<main>' takk@deb9:~$
読み込みの時は省略していましたが、書き込みモードを指定する必要があります。第2引数に”w”を指定します。
takk@deb9:~$ cat write.rb f=open("out.txt","w") f.puts("AAA") f.close() takk@deb9:~$
実行してみます。
takk@deb9:~$ ruby write.rb takk@deb9:~$ cat out.txt AAA takk@deb9:~$
out.txtが新規作成されて、内容が書き込まれているようです。
openはFile.openでもよいです。
takk@deb9:~$ cat write.rb f=File.open("out.txt","w") f.puts("BBB") f.close() takk@deb9:~$ ruby write.rb takk@deb9:~$ cat out.txt BBB takk@deb9:~$
openを使わずに一発で全行書き込むにはFile.writeを使います。
takk@deb9:~$ cat write-all.rb File.write("out.txt","HELLO\nHELLO\n") takk@deb9:~$ ruby write-all.rb takk@deb9:~$ cat out.txt HELLO HELLO takk@deb9:~$
配列の内容を書き込む場合は、ちょっと一工夫いりそうです。
takk@deb9:~$ cat write-all.rb arr = %w(aaa bbb ccc ddd eee) arr.push("") File.write("out.txt",arr.join("\n")) takk@deb9:~$ ruby write-all.rb takk@deb9:~$ cat out.txt aaa bbb ccc ddd eee takk@deb9:~$
コメント