Viral Shah
Viral Shah

Reputation: 71

build function arguments in ruby and reuse them for other functions

I have several functions in Ruby which I need to call with the same named parameter argument. ex.

config = { 'options' => {'key' => 'val' }, 'stuff' => '123' }

foo(arg1, arg2, **config)
bar(newarg1, newarg2, **config)

again I am using **config as in kwargs in python.

I don't know how to do the equivalent in Ruby.

Upvotes: 0

Views: 190

Answers (1)

Sean Vieira
Sean Vieira

Reputation: 160073

EDIT: Ruby 2.0 introduces the splat operator and keyword arguments, so if you are using Ruby >= 2.0 you can just use foo(arg, keyword: arg_default) and foo(1, **{:keyword => arg}). If you are using Ruby 1.x then what follows applies:


Ruby 1.x doesn't have a splat operator for keyword arguments (in fact, Ruby 1.x doesn't even have keyword arguments). Instead, you would simply have config as your last argument and users of your function can pass in a hash out of which you pull keys:

foo(arg1, arg2, config)
bar(newarg1, newarg2, config)

In Python you'd define foo and bar in this manner:

def foo(arg1, arg2, **config):
    # config now contains any keyword arguments passed to foo

And call it:

foo(1, 2, some="key", another="value")
# or if you have a hash from elsewhere
foo(1, 2, **{"some": "key", "another": "value"})

In Ruby a similar construct is achieved in this manner:

def foo(arg1, arg2, config={})
    # config is *still* a positional argument even though it has a default value!
    # do stuff with your configuration hash
    # as if it were a dictionary of keyword args
    # for example:
    default_config = {:options {:key => 'value'}, :stuff => 123}
    config = default_config.merge(config)
end

And it is called in this manner:

foo(1, 2, :some => 'key', :another => 'value')
# which translates into
foo(1, 2, {:some => 'key', :another => 'value'})
# the {} are optional for the last argument

If we were to translate that Ruby code directly into Python it would look something like this:

def foo(arg1, arg2, config=None):
    # This is not *quite* exact because we can still call `foo(1, 2, config={})`
    # but I think it is as close as you can get in Python
    if config is None:
        config = {}
    # Now we can do things with the config dictionary.

And you would call it:

# Note: no ** (splat) operator in front of our dictionary
foo(1, 2, {"some": "key", "another": "value"})

Upvotes: 5

Related Questions