1

読み込んでクラスに変換しようとしている名前と値のリストがあるので、Class.new.

私が望む最終結果は、次のように定義されているかのように機能する多くのクラスです。

module MyMod
  class AA < Base
    def self.value
      value1
    end
  end

  class AB < Base
    def self.value
      value2
    end
  end

  ...
end

私の現在のコードは次のようになります。

name = 'AA'
value = 'test'
MyMod.const_set name, Class.new(Base) do
  ???
end

名前の設定はうまく機能しますが、ブロックに入るために必要なものがわかりませんvalue。呼び出しは機能しません。defクロージャーvalueが失われるためです。

私は物事をうまく動かすことができました:

temp = const_set name, Class.new(Base)
temp.define_singleton_method(:value) { value }

ただし、のブロックでそれを行う方法があるはずですClass.newdefine_singleton_methodまた、実際にメソッドを正しい場所に配置しているかどうかはわかりません。私のテストでは機能しますが、メソッドが実際にあると思う場所にあるのか、呼び出しチェーンのどこかにあるのかはわかりません。class_variable_setattr_readerclass_eval、 、およびその他のさまざまな組み合わせを試しましたがinstance_eval、推測と確認に過ぎませんでした。私はまだメタプログラミングについて頭を悩ませていないと思います:-/

4

1 に答える 1

4

私があなたの質問を正しく理解していれば、これはあなたのために働くはずです:

class Base
end

class AA < Base

  name = :Blah
  klass = self.const_set name, Class.new(Base)

  class << klass
    def value
      __method__
    end
  end

end

p AA::Blah.value
#=> :value

更新:ブロックで定義したいようです:

class Base
end

class AA < Base

  name = :Blah
  klass = Class.new(Base) do

    class << self
      def value
        __method__
      end
    end

  end
  self.const_set name, klass

end

p AA::Blah.value

あなたはこれを試しています:

const_set name, Class.new(Base) do
  ...
end

const_setブロックが参照するのではなく参照しているため、機能しませんClass.new

define_singleton_method以上を好む場合class << self

class Base
end

class AA < Base

  name = :Blah
  klass = Class.new(Base) do

    self.define_singleton_method :value do
      __method__
    end

  end
  self.const_set name, klass

end

最後に、それらを一度に定義したい場合は、代わりに括弧を使用しますdo...end

class Base
end

class AA < Base

  name = :Blah
  self.const_set name, Class.new(Base) {

    self.define_singleton_method :value do
      __method__
    end

  }

end

これが実際のデモです

于 2012-11-23T13:10:42.853 に答える