3

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?

7
  • I don't understand but I want a defined number of arguments instead of an arg array (i.e. *args) - any example for this... Commented Nov 12, 2013 at 20:15
  • See updated question. Added examples under what I have. Commented Nov 12, 2013 at 20:20
  • what's the issue with your one ? Commented Nov 12, 2013 at 20:21
  • I would prefer to limit the number of arguments so I know exactly how many to call. Commented Nov 12, 2013 at 20:26
  • your post is not clear..sorry :) Commented Nov 12, 2013 at 20:27

2 Answers 2

3

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
Sign up to request clarification or add additional context in comments.

1 Comment

I half like this, half don't. Let me think about it. :)
3

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'.

1 Comment

Beautiful hack :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.