'How to dynamically create methods with parameter in ruby?
How can I dynamically create methods like this using ruby metaprogramming ?
class CommentBridge < Bridge
def id(comment)
comment.id
end
def message(comment)
comment.message
end
def votes_count(comment)
comment.votes_count
end
end
I tried this but it is not working.
['id', 'message', 'votes_count'].each do |method|
define_method "#{method}" do |parameter|
method(parameter.method)
end
end
Solution 1:[1]
You should use public_send to call methods based on their name:
['id', 'message', 'votes_count'].each do |method|
define_method "#{method}" do |parameter|
parameter.public_send(method)
end
end
Solution 2:[2]
I do not think that you need different comment every time (probably you do). So I'd recommend to simply get rid of this comment argument.
There are the options.
Using RubyOnRails (I see you question is tagged so) you can use delegate (as @SimpleLime has already commented)
class CommentBridge < Bridge
attr_reader :comment
def initialize(comment_)
@comment = comment_)
end
delegate :id, :message, :votes_count, to: :comment
end
In case of pure Ruby 2 use Forwardable:
class CommentBridge
extend Forwardable
attr_reader :comment
def initialize(comment_)
@comment = comment_)
end
def_delegators :comment, :id, :message, :votes_count
end
If you want to provide additional methods on top of you comment object and forward all the rest methods use SimpleDelegator (assuming that this Brigde in namgin means that your class is just a wrapper):
class CommentDecorator < SimpleDelegator
def hello
'hello'
end
end
comment = Commend.find(params[:id])
decorated_comment = CommentDecorator.new(comment)
You can also define 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
Finally, you can create your own delegation-DSL on top of define_method, but I think this is the extra in that case.
I don't think that method_missing or define_method inside loop is neat although it works.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | mrzasa |
| Solution 2 | Nick Roz |
