Ben*_*min 1 ruby module class include extend
我正在尝试定义一个名为"HTML"的类来扩展 Nokogiri - 它使用模块.
我尝试了以下方法:
require 'nokogiri'
class HTML
include Nokogiri
end
Run Code Online (Sandbox Code Playgroud)
和
require 'nokogiri'
class HTML
extend Nokogiri
end
Run Code Online (Sandbox Code Playgroud)
但到目前为止,类HTML仍然无法继承nokogiri中的所有函数.所以像这样的东西不起作用:
doc = HTML.new
doc.HTML(open('http://www.google.com/search?q=tenderlove'))
Run Code Online (Sandbox Code Playgroud)
用于#的未定义方法`HTML'(NoMethodError)
有谁知道如何设法继承模块的所有方法的类?
ram*_*ion 10
Nokogiri没有任何实例方法可以继承:
irb> Nokogiri.instance_methods
#=> []
Run Code Online (Sandbox Code Playgroud)
但通常情况下,你会使用 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模块的所有类方法作为你的类的实例方法.这有点不标准,这就是语法不支持它的原因.大多数程序员使用ruby模块作为Singleton模式 - 只需要一个Nokogiri,所以其他东西不应该使用它的方法.
您可以使用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)
Run Code Online (Sandbox Code Playgroud)
% 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中实现委托模式的一种方法(另一种方法是使用其中一个Delegator类).
| 归档时间: |
|
| 查看次数: |
2980 次 |
| 最近记录: |