Nokogiri には、継承するインスタンス メソッドがありません。
irb> Nokogiri.instance_methods
#=> []
しかし、通常は、extend
% ri 拡張
-------------------------------------------------- -------- オブジェクト#拡張
obj.extend(モジュール、...) => obj
-------------------------------------------------- ----------------------
として指定された各モジュールのインスタンス メソッドを obj に追加します。
パラメータ。
モジュールモッド
デフハロー
「Mod からこんにちは。\n」
終わり
終わり
クラス クラス
デフハロー
「クラスからこんにちは。\n」
終了 終了
k = クラス.新しい
k.hello #=> "クラスからこんにちは。\n"
k.extend(Mod) #=> #<クラス:0x401b3bc8>
k.hello #=> "モッズからこんにちは\n"
%
やりたいことは、Nokogiri モジュールのすべてのクラス メソッドをクラスのインスタンス メソッドとして使用することです。これは少し非標準であるため、構文でサポートされていません。ほとんどのプログラマーはシングルトン パターンに ruby モジュールを使用します。ノコギリは 1 つだけあればよいので、他のものはそのメソッドを使用できないはずです。
これを回避するために UndefinedMethods をハッキングすることもできますが、Nokogiri のバックエンドにコンパイル済みコードがあることを考えると、未定義のバグが発生する可能性があります。
通話を Nokogiri に転送できないと言っているわけではありません。
# nokogiri_wrapper.rb
require 'rubygems'
require 'nokogiri'
class NokogiriWrapper
def method_missing(meth, *args, &blk)
puts "call for #{meth.inspect}, #{args}, #{blk ? "with block" : "and no block"}"
if Nokogiri.methods.include? meth.to_s
puts "forwarding to Nokogiri"
Nokogiri.send(meth, *args, &blk)
else
puts "falling back to default behaviour"
super
end
end
end
html = "<html></html>"
puts "calling Nokogiri directly"
p Nokogiri.HTML(html)
wrapper = NokogiriWrapper.new
puts "calling Nokogiri through wrapper"
p wrapper.HTML(html)
puts "calling non-Nokogiri method with wrapper"
p(begin
wrapper.scooby_dooby_doo!
rescue NoMethodError => e
[e.message, e.backtrace]
end)
% ruby nokogiri_wrapper.rb
のこぎりに直接電話する
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html></html>
ラッパーを介して Nokogiri を呼び出す
:HTML、<html></html> の呼び出し、およびブロックなし
ノコギリに転送
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html></html>
ラッパーで Nokogiri 以外のメソッドを呼び出す
:scooby_dooby_doo! の呼び出し、ブロックなし
デフォルトの動作にフォールバックする
["未定義メソッド `scooby_dooby_doo!' for #<NokogiriWrapper:0x581f74>", ["nokogiri_wrapper.rb:12:in `method_missing'", "nokogiri_wrapper.rb:29"]]
これは、ruby で委任パターンを実装する 1 つの方法です (別の方法は、Delegator クラスの 1 つを使用することです)。