鋸山を継承するために、任意のインスタンスメソッドを持っていない:
irb> Nokogiri.instance_methods
#=> []
しかし、通常、あなたが何をしたいのかextend
% ri extend
---------------------------------------------------------- Object#extend
obj.extend(module, ...) => obj
------------------------------------------------------------------------
Adds to obj the instance methods from each module given as a
parameter.
module Mod
def hello
"Hello from Mod.\n"
end
end
class Klass
def hello
"Hello from Klass.\n"
end end
k = Klass.new
k.hello #=> "Hello from Klass.\n"
k.extend(Mod) #=> #<Klass:0x401b3bc8>
k.hello #=> "Hello from Mod.\n"
%
を使用するには、鋸山のすべてのクラスのメソッドを使用していますモジュールをクラスのインスタンスメソッドとして使用します。これは少し非標準的なものなので、シンタックスはそれをサポートしていません。ほとんどのプログラマは、シングルトンパターンにはルビモジュールを使用しています.Nokogiriは1つだけ必要なので、他のものはそのメソッドを使用できません。
これを回避するには、UndefinedMethodsを使っていくつかのハッキングを行うことができますが、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
calling Nokogiri directly
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html></html>
calling Nokogiri through wrapper
call for :HTML, <html></html>, and no block
forwarding to Nokogiri
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html></html>
calling non-Nokogiri method with wrapper
call for :scooby_dooby_doo!, , and no block
falling back to default behaviour
["undefined method `scooby_dooby_doo!' for #<NokogiriWrapper:0x581f74>", ["nokogiri_wrapper.rb:12:in `method_missing'", "nokogiri_wrapper.rb:29"]]
これはRubyで委任パターンを実装する1つの方法である(別の方法は、委任者のいずれかを使用することですクラス)。
ありがとうございました。 – Benjamin