I have a DSL in Ruby that works like so:
desc 'list all todos'
command :list do |c|
c.desc 'show todos in long form'
c.switch :l
c.action do |global,option,args|
# some code that's not relevant to this question
end
end
desc 'make a new todo'
command :new do |c|
# etc.
end
A fellow developer suggested I enhance my DSL to not require passing c
to the command
block, and thus not require the c.
for all
the methods inside; presumably, he implied I could make the following code work the same:
desc 'list all todos'
command :list do
desc 'show todos in long form'
switch :l
action do |global,option,args|
# some code that's not relevant to this question
end
end
desc 'make a new todo'
command :new do
# etc.
end
The code for command
looks something like
def command(*names)
command = make_command_object(..)
yield command
end
I tried several things and was unable to get it to work; I couldn't figure out how to change the context/binding of the code inside the command
block to be different than the default.
Any ideas on if this is possible and how I might do it?
Paste this code:
def evaluate(&block)
@self_before_instance_eval = eval "self", block.binding
instance_eval &block
end
def method_missing(method, *args, &block)
@self_before_instance_eval.send method, *args, &block
end
For more information, refer to this really good article here
Maybe
def command(*names, &blk)
command = make_command_object(..)
command.instance_eval(&blk)
end
can evaluate the block in the context of command object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With