Reputation: 221
I'm trying to refactor the code by defining the method dynamically with args. I've tried to use Define_method but it's throwing an error and I've been forced to define define_singleton_method.
Here is my code, I want to remove all the methods with call_* prefix.
def construct_payload(id, file_name, type)
case type
when 'Radio' then call_radio(id, file_name)
when 'Pan' then call_pan(id, file_name)
end
end
def call_radio(_id, _file_name)
base(_id).merge(radio(_file_name))
end
def call_pan(_id, _file_name)
base(_id).merge(pan(_file_name))
end
def base(_id)
{
"id": _id,
}
end
def radio(file)
{
"mode": "ds",
"file": file
}
end
def pan(file)
{
"mode": "pr",
"file": file
}
end
#enter code here
Is there a way I can define call_radio
and call_pan
methods dynamically?
Upvotes: 0
Views: 84
Reputation: 221
I think eval is the better choice to write less code
def construct_payload(id, file_name, type)
eval("base(id).merge(#{type}(file_name))")
end
def base(_id)
{
"id": _id,
}
end
def radio(file)
{
"mode": "ds",
"file": file
}
end
def pan(file)
{
"mode": "pr",
"file": file
}
end
Upvotes: 0
Reputation: 211540
case (type)
is often a strong sign you need to create subclasses instead of having an omniclass that just pretends to be different classes.
For example:
class Radio < BaseClass
def call(id, _file_name)
# ...
end
end
class Pan < BaseClass
def call(id, _file_name)
# ...
end
end
Then you just instantiate the right class and the right method gets called.
This is one of the principles of object-oriented design where you specialize classes where appropriate instead of having an unespecialized class that does many different, often contradictory things.
You could do some trickery with method_missing
or by calling define_method
but that's a lot of work compared to defining a subclass in this case.
Upvotes: 3