Question

This is what I'm looking to do.

# DSL Commands
command :foo, :name, :age
command :bar, :name

# Defines methods
def foo(name, age)
  # Do something
end

def bar(name)
  # Do something
end

Basically, I need a way to handle arguments through define_method, but I want a defined number of arguments instead of an arg array (i.e. *args)

This is what I have so far

def command(method, *args)
  define_method(method) do |*args|
    # Do something
  end
end

# Which would produce
def foo(*args)
  # Do something
end

def bar(*args)
  # Do something
end

Thoughts?

Was it helpful?

Solution

I think the best workaround for this would be do to something like the following:

def command(method, *names)
  count = names.length
  define_method(method) do |*args|

    raise ArgumentError.new(
      "wrong number of arguments (#{args.length} for #{count})"
    ) unless args.length == count

    # Do something
  end
end

OTHER TIPS

It's a little weird, but you can use some type of eval. instance_eval, module_eval or class_eval could be used for that purpose, depending on context. Something like that:

def command(method, *args)
  instance_eval <<-EOS, __FILE__, __LINE__ + 1
    def #{method}(#{args.join(', ')})
      # method body
    end
  EOS
end

This way you'll get exact number of arguments for each method. And yes, it may be a bit weirder than 'a little'.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top