Ruby のメソッド覚書
URI.extract(str)
文字列 str から URI を抽出する。
irb(main):001:0> require 'uri' => true irb(main):003:0> URI.extract('<img src="http://media.fc2.com/counter_img.php?id=50" style="visibility:hidden" alt="inserted by FC2 system" width="0" height="0">') => ["http://media.fc2.com/counter_img.php?id=50", "visibility:hidden"]
でも、これは何で "visibility:hidden" が入っているのかね。
※「逆引き」p.528
Module#prepend
「るりま」にはこうある。
指定したモジュールを self の継承チェインの先頭に「追加する」ことで self の定数、メソッド、モジュール変数を「上書き」します。
https://docs.ruby-lang.org/ja/2.2.0/method/Module/i/prepend.html
継承チェイン上で、self のモジュール/クラスよりも「手前」に 追加されるため、結果として self で定義されたメソッドは override されます。
用途としては、「モンキーパッチ」の代わりに使えて、それよりは上品(?)かも知れない。メソッドを上書きするわけであるが、super で元のメソッドも呼ぶことができる。
module A def capitalize "★★ " + super + " ★★" end end class String prepend A end puts "kyoto".capitalize #=>"★★ Kyoto ★★"
Object#extend
「るりま」にはこうある。
引数で指定したモジュールのインスタンスメソッドを self の特異メソッドとして追加します。
https://docs.ruby-lang.org/ja/2.2.0/method/Object/i/extend.html
Module#include は、クラス(のインスタンス)に機能を追加しますが、extend は、ある特定のオブジェクトだけにモジュールの機能を追加したいときに使用します。
特異メソッドをモジュールから追加するのに使う。
module A def star "★★ Gifu ★★" end end gifu = Object.new gifu.extend(A) puts gifu.star #=>"★★ Gifu ★★" class Gifu extend(A) end puts Gifu.star #=>"★★ Gifu ★★"
throw 〜 catch
「るりま」にはこうある。
Kernel.#catchとの組み合わせで大域脱出を行います。throw は同じ tag を指定した catch のブロックの終わりまでジャンプします。
https://docs.ruby-lang.org/ja/2.2.0/method/Kernel/m/throw.html
throw は探索時に呼び出しスタックをさかのぼるので、ジャンプ先は同じメソッド内にあるとは限りません。もし ensure節 が存在するならジャンプ前に実行します。
なんだって、こんなことが可能なのか。
def foo throw :exit, 25 end ret = catch(:exit) do begin foo some_process() # 絶対に実行されない 10 ensure puts "ensure" end end puts ret #=> ensure # 25
こりゃほとんど goto 文…。
ブロック付き Array.new
「るりま」にはこうある。
長さ size の配列を生成し、各要素のインデックスを引数としてブロックを実行し、 各要素の値をブロックの評価結果に設定します。
https://docs.ruby-lang.org/ja/2.3.0/method/Array/s/new.html
ブロックは要素毎に実行されるので、全要素をあるオブジェクトの複製にすることができます。
a = Array.new(3) {|i| (97 + i).chr} a[0].upcase! p a #=>["A", "b", "c"]
その他、多重配列を作るのも簡単。
Method(or Proc)#source_location
ソースコードのファイル名と行番号を配列で返す。
https://docs.ruby-lang.org/ja/2.3.0/method/Method/i/source_location.html
クラスメソッドで alias
こんな感じ。
class A def self.hoge; end class << self alias :fuga :hoge end end
配列の dup
配列 a のシャローコピー(浅いコピー)a.dup と、a[0..-1] は同等。以下のごとし。
irb(main):001:0> a = ["1", "2", "3"] => ["1", "2", "3"] irb(main):002:0> b = a.dup => ["1", "2", "3"] irb(main):003:0> a.object_id => 16653400 irb(main):004:0> b.object_id => 16633960 irb(main):005:0> a[0].object_id => 16653460 irb(main):006:0> b[0].object_id => 16653460 irb(main):007:0> c = a[0..-1] => ["1", "2", "3"] irb(main):008:0> c.object_id => 16989520 irb(main):009:0> c[0].object_id => 16653460
Module#append_features, Module#included
Module#append_features(mod) はモジュールが include される前に呼ばれ、引数 mod には include されるモジュール(乃至はクラス)が入る。
Module#included(mod)はモジュールが include された後に呼ばれる。引数 mod に include されるモジュール(乃至はクラス)が入るのは Module#append_features と同じ。
共に private メソッドである。
module A private class << self def append_features(mod) puts "#{self}が#{mod}にincludeされますよ" super end def included(mod) puts "#{self}が#{mod}にincludeされましたよ" end end end class X include A end #=> #"AがXにincludeされますよ" #"AがXにincludeされましたよ"
標準添付ライブラリの singleton.rb のソースを読んでいて、これを知らないがためにちんぷんかんぷんだった。
しかし、上の例でメソッドたちをモジュール A の特異メソッドにしなければならない理由がよくわからない。よくわからないというか、メソッドたちはそう定義されているのだな。