11

この Mixin を含むクラス名に基づいて、Mixin でクラス メソッドを動的に生成したいと考えています。

これが私の現在のコードです:

module MyModule  
  extend ActiveSupport::Concern  

  # def some_methods  
  #   ...  
  # end  

  module ClassMethods  

    # Here is where I'm stuck...
    define_method "#{self.name.downcase}_status" do  
      # do something...  
    end  

  end  
end  

class MyClass < ActiveRecord::Base  
  include MyModule  
end  

# What I'm trying to achieve:
MyClass.myclass_status

しかし、これにより次のメソッド名が得られます。

MyClass.mymodule::classmethods_status  

メソッド定義内の基本クラス名の取得は機能しますが (self、self.name ...)、メソッド名に対して機能させることはできません...

これまでのところ、私は試しました

define_method "#{self}"
define_method "#{self.name"
define_method "#{self.class}"
define_method "#{self.class.name}"
define_method "#{self.model_name}"
define_method "#{self.parent.name}"

しかし、これはどれもうまくいかないようです:/

基本クラス名を取得する方法はありますか (モジュールを含むクラスを何と呼ぶか​​わかりません)。私はこの問題に何時間も苦労してきましたが、きれいな解決策を見つけられないようです:(

ありがとう!

4

4 に答える 4

7

私はきれいな解決策を見つけました: using define_singleton_method(ruby v1.9.3で利用可能)

module MyModule  
  extend ActiveSupport::Concern  

  included do
    define_singleton_method "#{self.name}_status" do
      # do stuff
    end
  end

  # def some_methods  
  #   ...  
  # end  

  module ClassMethods  
    # Not needed anymore!
  end  
end  
于 2013-02-05T14:29:19.470 に答える
7

そのようにすることはできません - この時点では、どのクラス (または複数のクラス) がモジュールをインクルードしているかはまだわかっていません。

メソッドを定義するself.includedと、モジュールがインクルードされるたびに呼び出され、インクルードを実行するものが引数として渡されます。または、AS::Concern を使用しているため、次のことができます。

included do 
  #code here is executed in the context of the including class
end
于 2013-02-05T12:26:55.480 に答える
1

のために働くextend

module MyModule  
  def self.extended who
    define_method "#{who.name.downcase}_status" do
      p "Inside"
    end
  end
end  

class MyClass  
  extend MyModule  
end  

MyClass.myclass_status
于 2013-02-05T12:38:57.887 に答える
1

次のようなことができます。

module MyModule
  def self.included(base)
    (class << base; self; end).send(:define_method, "#{base.name.downcase}_status") do
      puts "Hey!"
  end

  base.extend(ClassMethods)
end

  module ClassMethods
    def other_method
      puts "Hi!"
    end
  end
end

class MyClass
  include MyModule
end

MyClass.myclass_status
MyClass.other_method
于 2013-02-05T12:28:48.600 に答える