如何在 ruby 中动态创建带参数的方法?
How to dynamically create methods with parameter in ruby?
如何使用 ruby 元编程动态创建这样的方法?
class CommentBridge < Bridge
def id(comment)
comment.id
end
def message(comment)
comment.message
end
def votes_count(comment)
comment.votes_count
end
end
我试过了,但没用。
['id', 'message', 'votes_count'].each do |method|
define_method "#{method}" do |parameter|
method(parameter.method)
end
end
您应该使用 public_send
根据名称调用方法:
['id', 'message', 'votes_count'].each do |method|
define_method "#{method}" do |parameter|
parameter.public_send(method)
end
end
我不认为你每次都需要不同的评论(可能你需要)。所以我建议简单地摆脱这个 comment
论点。
有选项。
使用 RubyOnRails(我看到你的问题是这样标记的)你可以使用 delegate
(@SimpleLime 已经评论过)
class CommentBridge < Bridge
attr_reader :comment
def initialize(comment_)
@comment = comment_)
end
delegate :id, :message, :votes_count, to: :comment
end
在纯Ruby2的情况下使用Forwardable
:
class CommentBridge
extend Forwardable
attr_reader :comment
def initialize(comment_)
@comment = comment_)
end
def_delegators :comment, :id, :message, :votes_count
end
如果您想在评论对象之上提供其他方法并转发所有其余方法,请使用 SimpleDelegator
(假设 namgin 中的这个 Brigde 意味着您的 class 只是一个包装器) :
class CommentDecorator < SimpleDelegator
def hello
'hello'
end
end
comment = Commend.find(params[:id])
decorated_comment = CommentDecorator.new(comment)
你也可以定义method missing
:
class CommentBridge < Bridge
attr_reader :comment
def initialize(comment_)
@comment = comment_)
end
def method_missing(m, *args)
if [:id, :message, :comment].include?(m)
comment.public_send(method, *args)
else
super
end
end
end
最后,您可以在 define_method
之上创建自己的 delegation-DSL,但我认为在这种情况下这是额外的。
我认为 method_missing
或 define_method
内部循环虽然有效,但并不整洁。
如何使用 ruby 元编程动态创建这样的方法?
class CommentBridge < Bridge
def id(comment)
comment.id
end
def message(comment)
comment.message
end
def votes_count(comment)
comment.votes_count
end
end
我试过了,但没用。
['id', 'message', 'votes_count'].each do |method|
define_method "#{method}" do |parameter|
method(parameter.method)
end
end
您应该使用 public_send
根据名称调用方法:
['id', 'message', 'votes_count'].each do |method|
define_method "#{method}" do |parameter|
parameter.public_send(method)
end
end
我不认为你每次都需要不同的评论(可能你需要)。所以我建议简单地摆脱这个 comment
论点。
有选项。
使用 RubyOnRails(我看到你的问题是这样标记的)你可以使用 delegate
(@SimpleLime 已经评论过)
class CommentBridge < Bridge
attr_reader :comment
def initialize(comment_)
@comment = comment_)
end
delegate :id, :message, :votes_count, to: :comment
end
在纯Ruby2的情况下使用Forwardable
:
class CommentBridge
extend Forwardable
attr_reader :comment
def initialize(comment_)
@comment = comment_)
end
def_delegators :comment, :id, :message, :votes_count
end
如果您想在评论对象之上提供其他方法并转发所有其余方法,请使用 SimpleDelegator
(假设 namgin 中的这个 Brigde 意味着您的 class 只是一个包装器) :
class CommentDecorator < SimpleDelegator
def hello
'hello'
end
end
comment = Commend.find(params[:id])
decorated_comment = CommentDecorator.new(comment)
你也可以定义method missing
:
class CommentBridge < Bridge
attr_reader :comment
def initialize(comment_)
@comment = comment_)
end
def method_missing(m, *args)
if [:id, :message, :comment].include?(m)
comment.public_send(method, *args)
else
super
end
end
end
最后,您可以在 define_method
之上创建自己的 delegation-DSL,但我认为在这种情况下这是额外的。
我认为 method_missing
或 define_method
内部循环虽然有效,但并不整洁。