4

为什么这不起作用:

class Myclass
include HTTParty

   def dosomething
     base_uri("some_url")
   end


end

base_uri 方法是 HTTParty 的一个类方法。如果我从我的类、任何实例方法之外或从类方法调用它,它工作正常,但是当尝试从实例方法调用它时,我得到“NoMethodError: undefined method `base_uri' for #”

为什么?不应该有某种方法可以从我的实例方法中引用 HTTParty 类,以便我可以调用该 HTTParty 类方法吗?

我可以将其更改为类方法,但我的类的每个实例都将具有相同的 base_uri 值。

4

2 回答 2

8

为什么它不起作用?因为这不是 Ruby 的工作方式。同样,这不起作用:

class Foo
  def self.utility_method; ...; end
  def inst_method
    utility_method  # Error! This instance has no method named "utility_method"
  end
end

您可以通过以下方式解决此问题:

class MyClass
  include HTTParty
  def dosomething
    HTTParty.base_uri("some_url")
  end
end

让我们更深入地了解方法查找如何与模块一起工作。首先,一些代码:

module M
  def self.m1; end
  def m2; end
end

class Foo
  include M
end
p Foo.methods     - Object.methods #=> []
p Foo.new.methods - Object.methods #=> [:m2]

class Bar
  extend M
end
p Bar.methods     - Object.methods #=> [:m2]
p Bar.new.methods - Object.methods #=> []

class Jim; end
j = Jim.new
j.extend M
p j.methods       - Object.methods #=> [:m2]

如我们所见,您可以使用extend来使对象(类或实例)对对象本身(而不是实例)使用模块的“实例”方法,但不能使模块的“类方法”成为被任何东西继承。你能得到的最接近的是这个成语:

module M2
  module ClassMethods
    def m1; end             # Define as an instance method of this sub-module!
  end
  extend ClassMethods       # Make all methods on the submodule also my own
  def self.included(k)
    k.extend(ClassMethods)  # When included in a class, extend that class with
  end                       # my special class methods

  def m2; end
end

class Foo
  include M2
end
p Foo.methods     - Object.methods #=> [:m1]
p Foo.new.methods - Object.methods #=> [:m2]

如果模块使用了HTTParty上述模式,并因此使该base_uri方法在您的 上可用MyClass,那么您可以这样做:

class MyClass
  include HTTParty
  def dosomething
    self.class.base_uri("some_url")
  end
end

...但这比直接引用拥有该方法的模块更重要。

最后,因为这可能对您有所帮助,所以这是我几年前制作的图表。(它缺少 Ruby 1.9 中的一些核心对象,BasicObject

Ruby 方法查找流程
(来源:phrogz.net

于 2012-07-19T21:30:27.297 回答
1
class Myclass
  include HTTParty

  def dosomething
    Myclass.base_uri("some_url")
  end

end
于 2012-07-19T22:33:58.710 回答