语法模块::方法名('字符串')如何工作



我最近有理由使用nokogiri gem来解析html,但在查看他们的文档时,我发现了这种在之前从未见过的ruby语法

html_doc = Nokogiri::HTML('<html><body><h1>Mr. Belvedere Fan Club</h1></body></html>')
xml_doc  = Nokogiri::XML('<root><aliens><alien><name>Alf</name></alien></aliens></root>')

我感兴趣的部分是Nokogiri::HTML("…")。这看起来很像方法调用,但我知道ruby方法名称不能用大写字母。所以我查看了nokogiri gem的代码文件,发现了以下定义

module Nokogiri
  class << self
     ###
     # Parse HTML.  Convenience method for Nokogiri::HTML::Document.parse
     def HTML thing, url = nil, encoding = nil, options = XML::ParseOptions::DEFAULT_HTML, &block
          Nokogiri::HTML::Document.parse(thing, url, encoding, options, &block)
     end
  end
 # more code
end

我试着复制相同的代码

module How
   class << self
      def DOESTHISWORK
         puts "In How Method"
      end
   end
end
How::DOESTHISWORK

但它不断返回错误"uninitialized constant How::DOESTHISWORK(NameError)"。我知道这与以大写字母开头的方法名称有关,但我只是没能弄清楚它在nokogiri中是如何工作的。

不同之处在于,在Nokogiri示例中,方法是用括号和一个参数值调用的,该参数值将其标识为方法调用。您的DOESTHISWORK方法不带参数,但可以用空括号调用,例如

irb(main):028:0> How::DOESTHISWORK()
In How Method
=> nil

如果你在你的方法中添加一个参数,也可以用来识别它是这样的方法:

irb(main):036:0> How::DOESTHISWORK 'some param'

以小写字母开头的方法名称是一种很好的做法,但没有强制执行。以大写字母开头的东西被认为是一个常数,并且会被这样查找,这就是为什么需要括号或参数来指示所引用的方法。另一个例子:

irb(main):051:0> def Example
irb(main):052:1> puts "An example!"
irb(main):053:1> end
=> nil
irb(main):054:0> Example
NameError: uninitialized constant Example
    from (irb):54
    from /Users/mike/.rbenv/versions/1.9.3-p194/bin/irb:12:in `<main>'
irb(main):055:0> Example()
An example!
=> nil

我也发现这篇文章对很有帮助

Ruby中对方法名称的限制是什么?

虽然不是强制性的,但很好的做法是以开头的方法名称小写字符,因为名称以大写字母开头是Ruby中的常量。仍然可以使用常量名称一个方法,但是如果没有圆括号就无法调用它,因为interper将查找作为常量的名称

最新更新