Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/debugging/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby:扩展模块的类_Ruby_Class_Include_Module_Extend - Fatal编程技术网

Ruby:扩展模块的类

Ruby:扩展模块的类,ruby,class,include,module,extend,Ruby,Class,Include,Module,Extend,我试图定义一个名为“HTML”的类来扩展Nokogiri,它使用模块 我尝试了以下方法: require 'nokogiri' class HTML include Nokogiri end 及 但到目前为止,HTML类不可能继承nokogiri中的所有函数。所以像这样的东西不起作用: doc = HTML.new doc.HTML(open('http://www.google.com/search?q=tenderlove')) #的未定义方法“HTML”(NoMethodEr

我试图定义一个名为“HTML”的类来扩展Nokogiri,它使用模块

我尝试了以下方法:

require 'nokogiri'

class HTML
    include Nokogiri
end

但到目前为止,HTML类不可能继承nokogiri中的所有函数。所以像这样的东西不起作用:

doc = HTML.new
doc.HTML(open('http://www.google.com/search?q=tenderlove'))
#的未定义方法“HTML”(NoMethodError)


有人知道我如何编写一个继承模块所有方法的类吗?

Nokogiri没有任何要继承的实例方法:

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" % %里延 ----------------------------------------------------------对象#扩展 对象扩展(模块,…)=>对象 ------------------------------------------------------------------------ 将每个模块中的实例方法作为 参数 模块模块 你好 “来自Mod的您好。\n” 结束 结束 克拉斯班 你好 “来自Klass的你好。\n” 结束 k=Klass.new k、 你好#=>“克拉斯你好。\n” k、 扩展(Mod)#=># k、 你好#=>“你好,来自国防部。\n” % 您要做的是使用Nokogiri模块的所有类方法作为类的实例方法。这有点不标准,这就是语法不支持它的原因。大多数程序员将ruby模块用于Singleton模式——只需要一个Nokogiri,所以其他东西不应该能够使用它的方法

您可以使用UndefinedMethods进行一些黑客攻击来绕过这个问题,但是考虑到Nokogiri在后端有一些编译代码,这可能会产生未定义的bug

这并不是说你不能把电话转给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)
#nokogiri#u wrapper.rb
需要“rubygems”
需要“nokogiri”
Nokogiriwraper类
def方法_缺失(meth、*args和blk)
将“调用#{meth.inspect}、#{args}、#{blk?”与block放在一起“:“并且没有block”}”
如果Nokogiri.methods.include?冰毒
将“转发至Nokogiri”
Nokogiri.send(meth、*args和blk)
其他的
将“退回默认行为”
超级的
结束
结束
结束
html=“”
将“直接呼叫Nokogiri”
p Nokogiri.HTML(HTML)
包装器=NokogiriWrapper.new
将“通过包装器调用Nokogiri”
p wrapper.HTML(HTML)
放置“使用包装器调用非Nokogiri方法”
p(开始
包装纸,史酷比!
救援命名错误=>e
[电子信息,电子回溯]
(完)
%ruby nokogiri_wrapper.rb 直接打电话给Nokogiri 通过包装器调用Nokogiri 调用:HTML,无块 转发至Nokogiri 使用包装器调用非Nokogiri方法 呼叫:史酷比!,没有障碍 回归违约行为 [“用于#”的未定义方法`scooby_dooby_doo!',[“nokogiri_wrapper.rb:12:in`method_missing'”,“nokogiri_wrapper.rb:29”]
这是在ruby中实现delegator模式的一种方法(另一种方法是使用delegator类之一)。

Nokogiri没有任何实例方法可继承:

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" % %里延 ----------------------------------------------------------对象#扩展 对象扩展(模块,…)=>对象 ------------------------------------------------------------------------ 将每个模块中的实例方法作为 参数 模块模块 你好 “来自Mod的您好。\n” 结束 结束 克拉斯班 你好 “来自Klass的你好。\n” 结束 k=Klass.new k、 你好#=>“克拉斯你好。\n” k、 扩展(Mod)#=># k、 你好#=>“你好,来自国防部。\n” % 您要做的是使用Nokogiri模块的所有类方法作为类的实例方法。这有点不标准,这就是语法不支持它的原因。大多数程序员将ruby模块用于Singleton模式——只需要一个Nokogiri,所以其他东西不应该能够使用它的方法

您可以使用UndefinedMethods进行一些黑客攻击来绕过这个问题,但是考虑到Nokogiri在后端有一些编译代码,这可能会产生未定义的bug

这并不是说你不能把电话转给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)
#nokogiri#u wrapper.rb
需要“rubygems”
需要“nokogiri”
Nokogiriwraper类
def方法_缺失(meth、*args和blk)
将“调用#{meth.inspect}、#{args}、#{blk?”与block放在一起“:“并且没有block”}”
如果Nokogiri.methods.include?冰毒
将“转发至Nokogiri”
Nokogiri.send(meth、*args和blk)
其他的
将“退回默认行为”
超级的
结束
结束
结束
html=“”
将“直接呼叫Nokogiri”
p Nokogiri.HTML(HTML)
包装器=NokogiriWrapper.new
将“通过包装器调用Nokogiri”
p wrapper.HTML(HTML)
放置“使用包装器调用非Nokogiri方法”
p(开始
包装纸,史酷比!
救援命名错误=>e
[电子信息,电子回溯]
(完)
%ruby nokogiri_wrapper.rb 直接打电话给Nokogiri 通过包装器调用Nokogiri 调用:HTML,无块 转发至Nokogiri 使用包装器调用非Nokogiri方法 呼叫:史酷比!,没有障碍 回归违约行为 [“用于#”的未定义方法`scooby_dooby_doo!',[“nokogiri_wrapper.rb:12:in`method_missing'”,“nokogiri_wrapper.rb:29”] 这是在ruby中实现delegator模式的一种方法(另一种方法是使用一个delegator类)