# Method interface - hash argument vs. named parameters

**URL:** <https://www.ruby-forum.com/t/method-interface-hash-argument-vs-named-parameters/190317>\
**Category:** Ruby\
**Created:** [June 17, 2010, 4:25pm UTC](https://www.ruby-forum.com/t/method-interface-hash-argument-vs-named-parameters/190317 "2010-06-17T16:25:10Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [June 17, 2010, 4:25pm UTC](https://www.ruby-forum.com/t/method-interface-hash-argument-vs-named-parameters/190317/1 "2010-06-17T16:25:10Z")

</div>

I’ve never run into this issue before, but I’m working on a method  
interface that is quite ‘dense’, and I need to be able to  
differentiate between a hash passed to a method and named parameters.  
i.e. All of these are valid:

foo(hash, :opt=\>val)  
foo(hash)  
foo(:opt=\>val)

However, there seems to be no way to distinguish that last the two  
forms.

Is there any way? Or am I stuck?

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [June 17, 2010, 5:26pm UTC](https://www.ruby-forum.com/t/method-interface-hash-argument-vs-named-parameters/190317/2 "2010-06-17T17:26:23Z")

</div>

On Thu, Jun 17, 2010 at 9:24 AM, Intransition [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> forms.
> 
> Is there any way? Or am I stuck?

I would expect stuck, because the difference seems nothing more than  
visual.  
(ie if the options hash was assigned to a var, rather than created  
within  
the arg list, then the last two would be exactly the same) though it  
does  
seem unusual that there is not a method like options\_given? the way  
there is  
a block\_given?

I suppose if this method interface is absolutely necessary, then a hack  
you  
might be able to get away with would be to check the keys to see if they  
match up with your options. But I would be embarrassed to show anyone  
such a  
solution 😉

Something to consider, though, whatever param the hash is an arg for, is  
optional (ie omitted in your third invocation). So perhaps it would fit  
better into the options hash, which you could then extract it from,  
inside  
the method:

def foo( options = Hash.new )  
the\_hash = options.delete(:the\_hash) { Hash.new }  
[the\_hash , options]  
end

hash = Hash[\*1…4]  
val = :val

foo( :the\_hash =\> hash , :opt =\> val ) # =\> [{1=\>2, 3=\>4},  
{:opt=\>:val}]  
foo( :the\_hash =\> hash ) # =\> [{1=\>2, 3=\>4}, {}]  
foo( :opt =\> val ) # =\> [{}, {:opt=\>:val}]

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [June 17, 2010, 10:15pm UTC](https://www.ruby-forum.com/t/method-interface-hash-argument-vs-named-parameters/190317/3 "2010-06-17T22:15:25Z")

</div>

> foo(hash)  
> foo(:opt=\>val)
> 
> However, there seems to be no way to distinguish that last the two  
> forms.

One possibility would be to check for known keys in the hash. If  
they’re there, assume it’s an options hash.  
Another might be to allow them to input it like  
:hash =\> hash  
if they ever want it that way.  
But you’re probably just stuck.  
-r  
ref: [GitHub - rdp/arguments: You don't have to wait until Ruby 2.0 to get (named|keyword) arguments. Has been tested with 1.8.6 and 1.9.1](http://github.com/rdp/arguments)

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [June 18, 2010, 1:21am UTC](https://www.ruby-forum.com/t/method-interface-hash-argument-vs-named-parameters/190317/4 "2010-06-18T01:21:49Z")

</div>

On Jun 17, 11:25 am, Josh C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> match up with your options. But I would be embarrassed to show anyone such a  
> end
> 
> hash = Hash[\*1…4]  
> val = :val
> 
> foo( :the\_hash =\> hash , :opt =\> val ) # =\> [{1=\>2, 3=\>4}, {:opt=\>:val}]  
> foo( :the\_hash =\> hash ) # =\> [{1=\>2, 3=\>4}, {}]  
> foo( :opt =\> val ) # =\> [{}, {:opt=\>:val}]

Yep. That’s what I thought. Appreciate the suggestion. In my case I’ve  
decided I’ll just have to do without the options hash.

I was hoping Ruby 1.9 at least would have had this licked. Early on  
there was talk of named parameters as:

def foo(hash=nil, \*\*opts)

But it never came to pass.

Thanks.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [June 18, 2010, 5:27am UTC](https://www.ruby-forum.com/t/method-interface-hash-argument-vs-named-parameters/190317/5 "2010-06-18T05:27:01Z")

</div>

On 2010-06-17 07:24:47 -0700, Intransition said:

> forms.
> 
> Is there any way? Or am I stuck?

If both the second and third option are valid then there is no way to  
distinguish between the two hashes. If you could narrow it down to one  
of them, you would be ok. If the hash is optional but the options  
aren’t, you can use:

def foo(hash\_or\_options, options=nil)  
hash = options ? hash\_or\_options : nil  
options = hash\_or\_options unless options  
…  
end

Alternatively, you can pass the original argument as part of the options  
hash

foo(:hash =\> hash, …)

I assume you’re using a more meaningful variable name than ‘hash’ in  
the real code, so this may suffice. I would not recommend mixing the  
two styles in the same method though (allowing a hash argument OR a  
:hash option).
