I'm trying 'borrow' some code from the Ruby Commander Gem. In the example in the Readme, they show a number of method calls that you place in your program like this:
require 'commander/import'
program :name, 'Foo Bar'
The method program is in the Commander module, Runner class. If you follow the require links you will come to the following module:
module Commander
module Delegates
%w(
add_command
command
program
run!
global_option
alias_command
default_command
always_trace!
never_trace!
).each do |meth|
eval <<-END, binding, __FILE__, __LINE__
def #{meth}(*args, &block)
::Commander::Runner.instance.#{meth}(*args, &block)
end
END
end
def defined_commands(*args, &block)
::Commander::Runner.instance.commands(*args, &block)
end
end
end
In the Commander module, Runner class, this is the pertinent code:
def self.instance
@singleton ||= new
end
def program(key, *args, &block)
if key == :help && !args.empty?
@program[:help] ||= {}
@program[:help][args.first] = args.at(1)
elsif key == :help_formatter && !args.empty?
@program[key] = (@help_formatter_aliases[args.first] || args.first)
elsif block
@program[key] = block
else
unless args.empty?
@program[key] = (args.count == 1 && args[0]) || args
end
@program[key]
end
end
I have copied this code into my own program and it doesn't appear to work as I get a method not found error on program. If I instantiate Runner as runner and call runner.program, it works fine.
In my version, which is all in one file, I have
module Repel
class Runner
# the same methods as above
end
module Delegates
def program(*args, &block)
::Repel::Runner.instance.program(*args, &block)
end
end
end
module Anthematic
include Repel
include Repel::Delegates
#runner = Runner.new
#runner.program :name, 'Anthematic'
program :name, 'Anthematic'
...
end
The error I get is:
: undefined method `program' for Anthematic:Module (NoMethodError)
The commented out code works when it is uncommented.
How do I get the code to work or, alternatively, is there a better way to do it? I have no idea what's going on in the rest of the eval statement. I'm aware that the number of arguments are off in the program def. I have the same problem with another method where they align.
Instead of
include Repel::Delegates
which includes module methods as instance methods, you should
extend Repel::Delegates
which will extend the class methods.