如何使用 define_method 创建类方法?
Posted
技术标签:
【中文标题】如何使用 define_method 创建类方法?【英文标题】:How do I use define_method to create class methods? 【发布时间】:2010-10-19 15:47:45 【问题描述】:如果您尝试以元编程方式创建类方法,这很有用:
def self.create_methods(method_name)
# To create instance methods:
define_method method_name do
...
end
# To create class methods that refer to the args on create_methods:
???
end
我的回答……
【问题讨论】:
【参考方案1】:你也可以在不依赖define_method的情况下做这样的事情:
A.class_eval do
def self.class_method_name(param)
puts param
end
end
A.class_method_name("hello") # outputs "hello" and returns nil
【讨论】:
【参考方案2】:如果你想从关注点动态定义类方法,可以在 Rails 中使用:
module Concerns::Testable
extend ActiveSupport::Concern
included do
singleton_class.instance_eval do
define_method(:test) do
puts 'test'
end
end
end
end
【讨论】:
【参考方案3】:这是 Ruby 1.8+ 中最简单的方法:
class A
class << self
def method_name
...
end
end
end
【讨论】:
我真的很喜欢这个。小巧,整洁,读起来很好,而且很便携。当然,你可以问我在 2013 年使用 ruby 1.8 在做什么......【参考方案4】:我认为在 Ruby 1.9 中你可以这样做:
class A
define_singleton_method :loudly do |message|
puts message.upcase
end
end
A.loudly "my message"
# >> MY MESSAGE
【讨论】:
还有singleton_class.define_method
@Pyro 澄清一下,你会去singleton_class.define_method :loudly do |message|
等吗?【参考方案5】:
源自:Jay 和 Why,他们还提供了使这个更漂亮的方法。
self.create_class_method(method_name)
(class << self; self; end).instance_eval do
define_method method_name do
...
end
end
end
更新:来自以下 VR 的贡献;一种更简洁的方法(只要您只以这种方式定义一个方法),它仍然是独立的:
self.create_class_method(method_name)
(class << self; self; end).send(:define_method, method_name) do
...
end
end
但请注意,使用 send() 来访问像 define_method() 这样的私有方法不一定是个好主意(我的理解是它在 Ruby 1.9 中将消失)。
【讨论】:
更好的(?)替代方法可能是将东西放入模块中,然后让您的 create_class_method 将模块扩展到类中???见:blog.jayfields.com/2008/07/ruby-underuse-of-modules.html【参考方案6】:我更喜欢使用 send 来调用 define_method,我也喜欢创建一个元类方法来访问元类:
class Object
def metaclass
class << self
self
end
end
end
class MyClass
# Defines MyClass.my_method
self.metaclass.send(:define_method, :my_method) do
...
end
end
【讨论】:
谢谢!绝对有办法让自己变得更好。但是,例如,如果您正在开发一个开源插件,我认为最好不要用metaclass
阻塞命名空间,所以很高兴知道简单、独立的速记。
我决定采用我原来的答案。我的理解是,如果在 Ruby 1.9 中消失,使用 send() 访问私有方法,所以这似乎不是一件好事。另外,如果您定义了多个方法,那么 instance_evaling 块会更干净。
@Vincent Robert 有什么链接可以解释元类方法的魔力吗?
类
以上是关于如何使用 define_method 创建类方法?的主要内容,如果未能解决你的问题,请参考以下文章