# Hash auto-true ({:a} == {:a =\> true})

**URL:** <https://www.ruby-forum.com/t/hash-auto-true-a-a-true/148020>\
**Category:** Ruby\
**Created:** [September 8, 2008, 11:04am UTC](https://www.ruby-forum.com/t/hash-auto-true-a-a-true/148020 "2008-09-08T11:04:40Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![woahdae](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/51bf81/32.png) [@woahdae](https://www.ruby-forum.com/u/woahdae)\
**Post date:** [September 8, 2008, 11:04am UTC](https://www.ruby-forum.com/t/hash-auto-true-a-a-true/148020/1 "2008-09-08T11:04:40Z")

</div>

I have a unix-inspired desire to pass arguments to a method where some  
are toggle flags and some are values, aka “bash$ method --flag  
–config=/etc/method”. I can think of a few ways to do it that are  
close, but if I had a hash that initiated value-less keys to true, I  
would have it.

Example:

method(:flag, :another, :config =\> “/etc/whatever”)

For some of the functionality I colud use \*args and check  
args.include?(:foo), but then I couldn’t pass in key-value pairs easily.

The closest way would be to use \*args to pass in things of the form  
method(:flag, [:config, “/etc/whatever”]), then use args.include?(:flag)  
for flags and args.assoc(:config)[1] for value-based options.

Example:

method(:flag, [:config, “/etc/whatever”])

ex. code:

if args.include?(:flag) do; stuff; end  
if args.assoc(:config) do; @config = args.assoc(:config)[1]; end

I’d have to make the args.assoc logic prettier with a helper method to  
set up default values, but that’s the basics of it. Much easier/prettier  
if I could modify Hash to auto-assign empty keys to true. Note that  
there’s a way to set the default value for empty keys from nil to  
another value (and even a proc), but this wouldn’t be what I want. I  
want empty keys to be nil, and specified lone keys set to true.

Thoughts? Anybody else think this would be really handy, or am I missing  
something?

---

<div class="post-metadata">

**Author:** ![woahdae](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/51bf81/32.png) [@woahdae](https://www.ruby-forum.com/u/woahdae)\
**Post date:** [September 8, 2008, 11:24am UTC](https://www.ruby-forum.com/t/hash-auto-true-a-a-true/148020/2 "2008-09-08T11:24:07Z")

</div>

2008/9/8 Woody P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> I have a unix-inspired desire to pass arguments to a method where some  
> are toggle flags and some are values, aka “bash$ method --flag  
> –config=/etc/method”. I can think of a few ways to do it that are  
> close, but if I had a hash that initiated value-less keys to true, I  
> would have it.

If you make the restriction that flags always come first you could do  
something like this:

def my\_method(arg1, arg2, \*args)  
options = (Hash === args.last) ? args.pop : {}  
puts args.inspect  
puts options.inspect  
end

my\_method(‘foo’, ‘bar’, :flag, :value =\> ‘something’)  
[:flag]  
{:value=\>“something”}

my\_method(‘foo’, ‘bar’, :flag)  
[:flag]  
{}

my\_method(‘foo’, ‘bar’, :value =\> ‘something’)  
[]  
{:value=\>“something”}

Then you can check for flags using args.include?(:foo), or you could  
loop  
over them and set them to true in the hash:

args.each { |key| options[key] = true }

---

<div class="post-metadata">

**Author:** ![woahdae](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/51bf81/32.png) [@woahdae](https://www.ruby-forum.com/u/woahdae)\
**Post date:** [September 8, 2008, 12:05pm UTC](https://www.ruby-forum.com/t/hash-auto-true-a-a-true/148020/3 "2008-09-08T12:05:01Z")

</div>

Yeah, that all would work pretty well. I think the restriction that  
value pairs come last is fair, and it’s a pretty clean solution. Thanks!

Now I’m wondering what it would take to define a hash explode (sidenote:  
is that what \* on \*args is called? explode?). How would one go about  
defining something like {}args that explodes args into a  
true-for-value-less hash (even using the code you posted)? I’m not sure  
exactly how \*args works internally, and it’s pretty hard to find info  
about it, actually. Any idea what kind of method it is, and how would  
you define another one?

Anyways, thanks for your suggestion. It’ll work great. I can’t help but  
wonder what the world would be like with a “hash explode” for this  
purpose, though 🙂

---

<div class="post-metadata">

**Author:** ![woahdae](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/51bf81/32.png) [@woahdae](https://www.ruby-forum.com/u/woahdae)\
**Post date:** [September 8, 2008, 12:18pm UTC](https://www.ruby-forum.com/t/hash-auto-true-a-a-true/148020/4 "2008-09-08T12:18:08Z")

</div>

> Now I’m wondering what it would take to define a hash explode (sidenote:  
> is that what \* on \*args is called? explode?). How would one go about  
> defining something like {}args that explodes args into a  
> true-for-value-less hash (even using the code you posted)? I’m not sure  
> exactly how \*args works internally, and it’s pretty hard to find info  
> about it, actually. Any idea what kind of method it is, and how would  
> you define another one?

Far as I know, the \*args is part of Ruby’s syntax, it’s not a method  
that  
you can change. Even if you could change it, I’ve no idea which class  
the  
method would be in. The best you can do is use \*args to mean “the  
remaining  
args” and pop the last one off if it’s a hash.

You could add a method in Hash to set one value to many keys:

class Hash  
def set\_many(value, \*keys)  
keys.each { |key| self[key] = value }  
end  
end

Then do the following:

def my\_method(arg1, arg2, \*args)  
options = (Hash === args.last) ? args.pop : {}  
options.set\_many(true, \*args)

# …

end

---

<div class="post-metadata">

**Author:** ![woahdae](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/51bf81/32.png) [@woahdae](https://www.ruby-forum.com/u/woahdae)\
**Post date:** [September 8, 2008, 12:30pm UTC](https://www.ruby-forum.com/t/hash-auto-true-a-a-true/148020/5 "2008-09-08T12:30:27Z")

</div>

> def my\_method(arg1, arg2, \*args)  
> options = (Hash === args.last) ? args.pop : {}  
> options.set\_many(true, \*args)
> 
> # …
> 
> end

Or this, to build the hash from the args array:

module Enumerable  
def to\_option\_hash(value = true)  
ary = entries  
options = (Hash === ary.last) ? ary.pop : {}  
ary.each { |key| options[key] = value }  
options  
end  
end

Then you can do:

def my\_method(arg1, arg2, \*options)  
options = options.to\_option\_hash

# …

end

---

<div class="post-metadata">

**Author:** ![woahdae](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/51bf81/32.png) [@woahdae](https://www.ruby-forum.com/u/woahdae)\
**Post date:** [September 8, 2008, 12:41pm UTC](https://www.ruby-forum.com/t/hash-auto-true-a-a-true/148020/6 "2008-09-08T12:41:55Z")

</div>

> backwards compatible with my\_method(:flag =\> true, :config =\>  
> “whatever”)

err, following your examlpe, my\_method(“arg1”, “arg2”, :flag =\> true,  
:config =\> “whatever”).

---

<div class="post-metadata">

**Author:** ![woahdae](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/51bf81/32.png) [@woahdae](https://www.ruby-forum.com/u/woahdae)\
**Post date:** [September 8, 2008, 12:39pm UTC](https://www.ruby-forum.com/t/hash-auto-true-a-a-true/148020/7 "2008-09-08T12:39:23Z")

</div>

> def my\_method(arg1, arg2, \*options)  
> options = options.to\_option\_hash
> 
> # …
> 
> end

That’s pretty cool. I was thinking something similar, but got stuck on  
naming the method :-p

The advantage of this strategy over args.include?(:flag) is that it’s  
backwards compatible with my\_method(:flag =\> true, :config =\>  
“whatever”). Also, although I’m sure it’s negligible, after you hash it  
you have a seek time of O(1), whereas I assume you have a seek time of  
O(n) every time you call include?(). But mostly the backwards  
compatibility.
