2011/02/24

Rubyの面白いところ Part 12 「標準ライブラリにバックトレース機能がある」

LLな言語を使う開発者は、どうにもIDEを使わないイメージがあるのですが、標準ライブラリにトレースバック機能 があるんですねぇ…。

  1. #!/usr/bin/ruby  
  2.   
  3. def foo  
  4.   p caller(0) # ["caller.rb:4:in `foo'", "caller.rb:11:in `bar'", "caller.rb:14"]  
  5.   p caller(1) # ["caller.rb:11:in `bar'", "caller.rb:14"]  
  6.   p caller(2) # ["caller.rb:14"]  
  7.   p caller(3) # []  
  8. end  
  9.   
  10. def bar  
  11.   foo  
  12. end  
  13.   
  14. bar  
ファイル名、行番号、メソッド名を出力しています(参考)。

2011/02/17

Rubyの面白いところ Part 11 「caseとbreakは他言語と動作が異なる」

breakはもっとも内側のループを脱出します。ループとは

  • while
  • until
  • for
  • イテレータ
のいずれかを指します。 C言語とは異なり、breakはループを脱出する作用だけを持ち、caseを抜ける作用は持ちません。(参考)

ほっほー。試しに下記を実行するとfirstが出力された。つまり、2つ目からのwhenはifではなくelse ifなんですね。

  1. a = 1  
  2. case a  
  3. when 1  
  4.   p "first"  
  5. when 1  
  6.   p "second" # never come here  
  7. else  
  8.   p "else" # never come here  
  9. end  

2011/05/11 追記:
動物本を見るとelse ifという表現はあまりよろしくない気がしました。

プログラミング言語 Rubyより

他の言語のswitch文は、単純に適切なcaseラベルの先頭に制御を移すだけである。そこから制御は継続され、他のcaseラベルに「落下」することもある。この落下の動作により、複数のcase節が同じコードブロックを参照できるのである。Rubyでは、個々のwhen節にカンマ区切りの複数の指揮を並べられるようにして、同じ目的を達している。Rubyのcase文は落下しない。

プログラミング言語 Ruby 第2版 131ページ caseとswitch
  1. def hasValue?(x)      # hasValue?という名前のメソッドを定義する  
  2.   case x              # xの値に基づく多方向条件分岐  
  3.   when nil, [], "", 0 # nil===x || []===x || ""===x || 0===xなら  
  4.     false             # メソッドの戻り値はfalse  
  5.   else                # そうでなければ  
  6.     true              # メソッドの戻り値はtrue  
  7.   end  
  8. end  

2011/02/16

Rubyの面白いところ Part 10 「多重代入における*の取り扱い」

多重代入は複数の式または配列から同時に代入を行う。左辺の最後の式の直前に*がついていると、対応する左辺のない余った要素が配列として代入される。余った要素が無い時には空の配列が代入される。

  1. foo, bar = [1, 2] # foo = 1; bar = 2  
  2. *foo = 1, 2, 3 # foo = [1, 2, 3]  

ここまでは便利だなぁーと思うのですが、次の仕様がどう有効活用するのかよくわからない...

特に最後の単体の*はメソッド呼び出しにおいて引数を完全に無視したいときに使用できます。

  1. def foo(*)  
  2. end  
  3. foo(1,2,3) # ok  
  4.   
  5. def bar()  
  6. end  
  7. bar(1,2,3) # in `bar': wrong number of arguments (3 for 0) (ArgumentError)  

何か有効活用する意味があると思うんですが、思いつきません...

参考: Rubyリファレンスマニュアル

2011/02/15

Rubyの面白いところ Part 9 「ローカル変数の宣言と寿命」

ローカル変数のスコープは、宣言した位置からその変数が宣言されたブロック、メソッド定義、またはクラス/モジュール定義の終りまでです(参考)。

  1. 2.times {  
  2.   p defined?(v) # 2回ともnilなことに注意  
  3.   v = 1  
  4.   p defined?(v) # "local-variable"  
  5. }  

参考: Rubyの面白いところ Part 7 「NameErrorが起こらないとき」