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がありませんが、それ以外の場合は引き続き適用できます。PDFバージョンをクリックしてください。図の注#3が特に適用可能です。)

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 に答える