你如何处理参数&在 Ruby 中动态定义方法时会阻塞吗?

发布于 2024-12-21 12:30:09 字数 705 浏览 1 评论 0原文

下面是一个可以动态向方法添加日志记录的类的代码。这适用于方法不带参数且不接受块的情况。

如何重写代码,以便即使它接受参数并接受块,也可以添加方法的日志记录?

class X
    def greet
        puts "hi"
    end

    def self.add_logging(method_name)
        alias_method("original_#{method_name}".to_sym, method_name) 

        #How do i rewrie this to account for method_name's arguments and ability to accept a block?
        define_method(method_name) do
            puts "calling #{method_name}"
            send "original_#{method_name}".to_sym
            puts "done #{method_name}"
        end
    end
end

x = X.new
x.greet
X.add_logging(:greet)
x.greet

输出

>hi 
>calling greet 
>hi 
>done greet

Below is code for a class that can dynamically add logging to a method. This works in the case where the method takes no parameters and accepts no block.

How can I rewrite the code, so that I can add logging of a method even if it accepts parameters and accepts a block?

class X
    def greet
        puts "hi"
    end

    def self.add_logging(method_name)
        alias_method("original_#{method_name}".to_sym, method_name) 

        #How do i rewrie this to account for method_name's arguments and ability to accept a block?
        define_method(method_name) do
            puts "calling #{method_name}"
            send "original_#{method_name}".to_sym
            puts "done #{method_name}"
        end
    end
end

x = X.new
x.greet
X.add_logging(:greet)
x.greet

outputs

>hi 
>calling greet 
>hi 
>done greet

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

往昔成烟 2024-12-28 12:30:09
class X
  def self.add_logging method
    alias_method "original_#{method}", method
    define_method(method) do |*args, &pr|
      puts "calling #{method}"
      send "original_#{method}", *args, &pr
      puts "done #{method}"
    end
  end
  def greet person
    puts "hi #{person}"
  end
end

x = X.new
x.greet("Joe")
X.add_logging(:greet)
x.greet("Jane")

将给出:

hi Joe
calling greet
hi Jane
done greet
class X
  def self.add_logging method
    alias_method "original_#{method}", method
    define_method(method) do |*args, &pr|
      puts "calling #{method}"
      send "original_#{method}", *args, &pr
      puts "done #{method}"
    end
  end
  def greet person
    puts "hi #{person}"
  end
end

x = X.new
x.greet("Joe")
X.add_logging(:greet)
x.greet("Jane")

will give:

hi Joe
calling greet
hi Jane
done greet
是伱的 2024-12-28 12:30:09

据我所知,define_method-methods 块接受参数,这些参数代表方法参数,因此我建议如下:

define_method(method_name) do |*arguments|
        puts "calling #{method_name}"
        send "original_#{method_name}".to_sym, *arguments
        puts "done #{method_name}"
end

块中 do-part 中的 *arguments 将调用方法 method_name 时发送的所有参数包装到数组中,并且 *arguments > 在发送方法调用中再次扩展它们以在原始方法中使用。

As far as i know the define_method-methods block accepts parameters, which represent the method parameters so i'd suggest the following:

define_method(method_name) do |*arguments|
        puts "calling #{method_name}"
        send "original_#{method_name}".to_sym, *arguments
        puts "done #{method_name}"
end

*arguments in the do-part in the block wraps all arguments/parameters which are sent when calling the method method_name into an array, and *arguments in the send-method call expands them again for use in the original method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文