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

所以这里的技巧是先为每个方法创建一个别名,然后通过“打印格式化方法名称”+“原始方法即别名”重新定义方法。它也由Here 文档(<<-END) 动态处理。

但是由于每个方法的重新定义都会调用它的原始方法,最终不可能删除_方法取消定义别名。我认为将所有这些别名 (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 回答