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 の定数、メソッド、モジュール変数を「上書き」します。
継承チェイン上で、self のモジュール/クラスよりも「手前」に 追加されるため、結果として self で定義されたメソッドは override されます。

https://docs.ruby-lang.org/ja/2.2.0/method/Module/i/prepend.html

 
用途としては、「モンキーパッチ」の代わりに使えて、それよりは上品(?)かも知れない。メソッドを上書きするわけであるが、super で元のメソッドも呼ぶことができる。

module A
  def capitalize
    "★★ " + super + " ★★"
  end
end

class String
  prepend A
end

puts "kyoto".capitalize    #=>"★★ Kyoto ★★"

 

Object#extend

「るりま」にはこうある。

引数で指定したモジュールのインスタンスメソッドを self の特異メソッドとして追加します。
Module#include は、クラス(のインスタンス)に機能を追加しますが、extend は、ある特定のオブジェクトだけにモジュールの機能を追加したいときに使用します。

https://docs.ruby-lang.org/ja/2.2.0/method/Object/i/extend.html

 
特異メソッドをモジュールから追加するのに使う。

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 のブロックの終わりまでジャンプします。
throw は探索時に呼び出しスタックをさかのぼるので、ジャンプ先は同じメソッド内にあるとは限りません。もし ensure節 が存在するならジャンプ前に実行します。

https://docs.ruby-lang.org/ja/2.2.0/method/Kernel/m/throw.html

なんだって、こんなことが可能なのか。

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

クラスメソッドに alias を付ける - Qiita
 

配列の 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 の特異メソッドにしなければならない理由がよくわからない。よくわからないというか、メソッドたちはそう定義されているのだな。