とんちゃんといっしょ

Cloudに関する技術とか日常とかについて書いたり書かなかったり

Ruby 2.0の機能解説メモ(Kernel)

久しぶり更新。


社内の読書会でRuby 2.0のリリースノートを読んで2.0の新機能を学ぼうという提案が通った。
自分の担当部分を軽くまとめておく。

  * Kernel
    * added method:
      * added Kernel#Hash conversion method like Array() or Float().
      * added Kernel#__dir__ which returns the absolute path of the
        directory of the file from which this method is called.
      * added Kernel#caller_locations which returns an array of
        frame information objects.
    * extended method:
      * Kernel#warn accepts multiple args in like puts.
      * Kernel#caller accepts second optional argument `n' which specify
        required caller size.
      * Kernel#to_enum and enum_for accept a block for lazy size evaluation.
    * incompatible changes:
      * system() and exec() closes non-standard file descriptors
        (The default of :close_others option is changed to true by default.)
      * respond_to? against a protected method now returns false unless
        the second argument is true.
      * __callee__ has returned to the original behavior, and now
        returns the called name but not the original name in an
        aliased method.
      * Kernel#inspect does not call #to_s anymore
        (it used to call redefined #to_s).
  • 追加されたメソッド
    • Kernel#Hash

Array()とかFloat()と同じようにHashもできるようになる。
Array()の説明を見ると多分to_h()メソッドがあるオブジェクトを渡すとHashにしてくれる模様。
・・・to_h()メソッド呼べるオブジェクト少なくない?
なのでサンプルはNilClass。

pry(main)> Array(1..3) # 1.9系でも可能
=> [1, 2, 3]
pry(main)> Hash(nil)   # 2.0系で可能
=> {}
    • Kernel#__dir__

__dir__メソッドを呼んだファイルの絶対パスを表示してくれる

puts __dir__
% ruby __dir__.rb
/tmp/ruby2
    • Kernel#caller_locations

スタックに積まれたメソッドの呼び出し元を配列として返してくれる。

  1 def fiz
  2   baz
  3 end
  4 
  5 def baz
  6   p caller_locations
  7 end
  8 
  9 fiz
% ruby caller_locations.rb
["caller_locations.rb:2:in `fiz'", "caller_locations.rb:9:in `
'"]
  • 拡張されたメソッド
    • Kernel#warn

#putsみたいに複数の引数を受け取れるようになった

 1 warn "fiz", "buz"
% ruby warn.rb
warn.rb:1:in `warn': wrong number of arguments(2 for 1) (ArgumentError)
	from warn.rb:1:in `
'
% ruby warn.rb
fiz
buz
    • Kernel#caller

呼び出し元の情報ををバックトレース(文字列の配列)として返すにあたり、範囲が指定できるようになった。

  1 #encoding: utf-8
  2 
  3 def foo
  4   p caller(0)    # 1.9系でも可能
  5   p caller(0, 1) # 2.0系で可能
  6 end
  7 
  8 def bar
  9   foo
 10 end
 11 
 12 bar

% ruby caller.rb
["caller.rb:4:in `foo'", "caller.rb:9:in `bar'", "caller.rb:12:in `<main>'"]
["caller.rb:5:in `foo'"]

Enumerator#lazyに対応・・・でいいのかな?

    • 互換性のないメソッド
      • Kernel#system()
      • Kernel#exec()

スタンダードではないファイルのディスクリプタを閉じる
#スタンダードじゃないファイルって何?

      • Kernel#respond_to?

protectedのメソッドが定義されているかどうかを調べる際に、第二引数にtrueを付けないとfalseになる。

  1 module Kernel
  2   def hoge
  3     "hoge"
  4   end
  5   protected :hoge
  6 end
  7 
  8 puts hoge
  9 puts respond_to? :hoge
 10 puts respond_to? :hoge, true
% ruby respond_to.rb
hoge
true
true
% ruby respond_to.rb
hoge
false
true
      • Kernel#__callee__

2.0以前はエイリアスされたメソッド名ではなく、元のメソッド名を表示していたが、2.0からはエイリアスされたメソッド名を返すようになった。

  1 class Foo
  2   def bar
  3     puts __callee__
  4   end
  5   alias foo bar
  6 end
  7 
  8 obj = Foo.new
  9 obj.foo
 10 obj.bar
% ruby __callee__.rb
bar
bar
% ruby __callee__.rb
foo
bar
      • Kernel#inspect

再定義された#to_sを呼ぶから#to_sを呼ばなくなったらしい。
結局#to_s呼んでるし、最初から再定義された#to_sを呼ぶって書けばいいんじゃ・・・