21


6

外部のローカル変数を参照するクラスメソッドを動的に定義する方法は?
class C
end

var = "I am a local var outside"

C.class_eval do
   def self.a_class_method
     puts var
   end
end

`def`が新しいスコープを作成したため、これは正しくありません。 また、 `define_method`を使用すると、新しいスコープを作成せずにインスタンスメソッドを作成できることも知っていますが、私のポイントは* classメソッド*を定義する方法です。

2 Answer


51


クラスメソッドは実際にはRubyには存在せず、クラスオブジェクトのシングルトンメソッドにすぎません。 シングルトンメソッドも実際には存在しません。オブジェクトのシングルトンクラスの単なる通常のインスタンスメソッドです。

Module#define_method`を使用して)インスタンスメソッドを定義する方法をすでに知っているので、知っておく必要があることはすべて知っています。 `C`の代わりに C`のシングルトンクラスで `class_eval`を呼び出すだけです。

(class << C; self end).class_eval do
  define_method(:a_class_method) do
    puts var
  end
end

現在のバージョンのRubyには、これを簡単にするための `singleton_class`メソッドがあります。

C.singleton_class.class_eval do
  define_method(:a_class_method) do
    puts var
  end
end

しかし実際には、Rubyの現在のバージョンには `Module#define_singleton_method`もあるため、この特定のケースでは不要です。

C.define_singleton_method(:a_class_method) do
  puts var
end


1


この方法で簡単にできます

class << C
  define_method(:a_class_method) do
     # do something
  end
end