1

私はまだ多くの点でRubyに慣れていないので、これをしようとして少し立ち往生しています(モジュール?または基本クラスを介して?)。

クラスで実行される各メソッド呼び出しに対して「プット」を実行したいと考えています。非常に単純な形式のキュウリ フォーマッタに似ています。つまり、次のようになります。

class MyClass
    def method_a
        puts 'doing some stuff'
    end 
end

出力は次のようになります。

MyClass.new.method_a => 'methods_a', 'doing some stuff'

さらに重要なことは、それを任意のクラスの任意のメソッドに適用することです (コードを散らかさずに動的に)。'method_a' => 'Method A' のようにフォーマットを適用したいと思います。これを行う最善の方法は何ですか?AOP フレームワーク?

4

2 に答える 2

2
class MyClass
  def method_a
    puts "Doing A..."
  end

  def method_b
    puts "Doing B..."
  end

  def self.call_before_all_methods
    all_instance_methods = instance_methods - Class.instance_methods
    all_instance_methods.each do |x|
      class_eval <<-END
        alias old_#{x} #{x}
        def #{x}
          print "\'#{x.to_s.split('_').each{|x| x.capitalize!}.join(' ')}\', "
          old_#{x}
        end
        # remove_method old_#{x}.to_sym
      END
    end
  end

  private_class_method :call_before_all_methods
  call_before_all_methods
end

a = MyClass.new
a.method_a
a.method_b

ここでのコツは、最初に各メソッドのエイリアスを作成し、次に「出力形式のメソッド名」+「エイリアスである元のメソッド」でメソッドを再定義することです。また、ヒア ドキュメント(<<-END) によって動的に処理されます。

しかし、各メソッドの再定義は元のメソッドを呼び出すため、最終的にremove_methodやエイリアスのundefを行うことはできません。これらすべてのエイリアス (old_method_a、old_method_b) をそのままにしておくことは大したことではないと思います。

于 2012-09-15T18:42:35.590 に答える
0

なぜこれをしたいのかわかりませんが、ここにいます(before_filterは別として):

class MyClass
  def puts_all(&blk)
    # get all instance_methods, also including default ones, so remove them by - Class.instance_methods
    all_other_methods = self.class.instance_methods - Class.instance_methods
    # remove the method name itself dynamically by saying __callee__
    all_other_methods.delete(__callee__)
    # formatting as per your need
    all_other_methods.each do |x|
      print "#{x.to_s.split('_').each{|x| x.capitalize!}.join(' ')}, "
      send(x)
    end
  end

  def method_a
    puts "Doing A..."
  end

  def method_b
    puts "Doing B..."
  end

  def another_fancy_method
    puts "Doing fancy..."
  end
end

MyClass.new.puts_all
#=> Method A, Doing A...
#=> Method B, Doing B...
#=> Another Fancy Method, Doing fancy...

したがって、これを動的に実現するには、単にinstance_methods_ callee _を使用できます。

于 2012-09-06T12:45:14.230 に答える