Passing only a hash key, with no value, as an option

M

Max Williams

I'm using the method of parameter passing where i have one 'regular'
parameter and then a hash of options:

def chunkify(something, options = {})
...
end

I want to have it so that the user can just pass a key through without
having to set it to anything, eg

dinner = chunkify(bacon, :extra_fine)

However, 'extra_fine' is just being treated as a symbol, rather than a
hash key, and so 'options' is simply the symbol :extra_fine, rather than
the hash {:extra_fine => nil}.

I can fix this by passing :extra_fine => true to the method, but can i
set up the method so it will just take the hash key, and maybe some
other hash_keys, some with and some without values?

thanks
max
 
R

Robert Klemme

2008/3/12 said:
I'm using the method of parameter passing where i have one 'regular'
parameter and then a hash of options:

def chunkify(something, options = {})
...
end

I want to have it so that the user can just pass a key through without
having to set it to anything, eg

dinner = chunkify(bacon, :extra_fine)

However, 'extra_fine' is just being treated as a symbol, rather than a
hash key, and so 'options' is simply the symbol :extra_fine, rather than
the hash {:extra_fine => nil}.

I can fix this by passing :extra_fine => true to the method, but can i
set up the method so it will just take the hash key, and maybe some
other hash_keys, some with and some without values?

Nope. You will have to use chunkify(something, *options) and do the
processing yourself. Note that in no case can you mix Hash entries
with and without values. But you can do

irb(main):006:0> def x(*a)p a end
=> nil
irb(main):007:0> x:)foo, :bar => 2)
[:foo, {:bar=>2}]
=> nil
irb(main):008:0>

Kind regards

robert
 
D

David A. Black

Hi --

I'm using the method of parameter passing where i have one 'regular'
parameter and then a hash of options:

def chunkify(something, options = {})
...
end

I want to have it so that the user can just pass a key through without
having to set it to anything, eg

dinner = chunkify(bacon, :extra_fine)

However, 'extra_fine' is just being treated as a symbol, rather than a
hash key, and so 'options' is simply the symbol :extra_fine, rather than
the hash {:extra_fine => nil}.

I can fix this by passing :extra_fine => true to the method, but can i
set up the method so it will just take the hash key, and maybe some
other hash_keys, some with and some without values?

You're over-thinking this a bit. :extra_fine isn't any more a hash key
than 100 is in this:

do_something(100)

The only thing that tells Ruby that you want a hash as the last
argument, in the absence of curly braces, is the hash separator (=>).

do_something(100 => "C")

There's also no such thing as a hash key that isn't part of a hash. It
sounds like what you want to do is pass multiple objects to your
method and create a hash from them inside the method.


David
 
M

Max Williams

There's also no such thing as a hash key that isn't part of a hash. It
sounds like what you want to do is pass multiple objects to your
method and create a hash from them inside the method.


David

Hi David

I know what you're saying, it is a bit clumsy.

Where i'm coming from is that i often use a lot of options that are set
to true by the user of the method if they want to use them, which does
work nicely due to options[:foo] evaluating to nil if the user didn't
set it, allowing me to have tests like
if options[:foo] #missing key equivalent to :foo => false
do_extra_stuff
end

I just thought it would be even nicer to have the user just be able to
pass the hash key, rather than have to keep adding "=> true". So the
presence of a hash key acts like a switch which i can test with

if options.has_key? :foo
do_extra_stuff
end

I thought i'd seen this functionality in rails, where we can pass just a
hash key without bothering to set it, if we want to switch something on
or off.
 
R

Robert Klemme

2008/3/12 said:
Hi David

I know what you're saying, it is a bit clumsy.

Pardon me, but it seems David's words did not sink in since you are
still talking about a Hash key where you mean "symbol".
Where i'm coming from is that i often use a lot of options that are set
to true by the user of the method if they want to use them, which does
work nicely due to options[:foo] evaluating to nil if the user didn't
set it, allowing me to have tests like
if options[:foo] #missing key equivalent to :foo => false
do_extra_stuff
end

I just thought it would be even nicer to have the user just be able to
pass the hash key, rather than have to keep adding "=> true". So the
presence of a hash key acts like a switch which i can test with

if options.has_key? :foo
do_extra_stuff
end

I thought i'd seen this functionality in rails, where we can pass just a
hash key without bothering to set it, if we want to switch something on
or off.

If you need a set of boolean flags then you can just use an array

irb(main):008:0> def x(*opts)
irb(main):009:1> settings = opts.inject({}){|h,o| h[o]=true;h}
irb(main):010:1> end
=> nil
irb(main):011:0> x:)foo, :lazy)
=> {:lazy=>true, :foo=>true}
irb(main):012:0>

Kind regards

robert
 
P

Paul Mckibbin

Max said:
I'm using the method of parameter passing where i have one 'regular'
parameter and then a hash of options:

def chunkify(something, options = {})
...
end

I want to have it so that the user can just pass a key through without
having to set it to anything, eg

dinner = chunkify(bacon, :extra_fine)

However, 'extra_fine' is just being treated as a symbol, rather than a
hash key, and so 'options' is simply the symbol :extra_fine, rather than
the hash {:extra_fine => nil}.
extra_fine is a symbol, as other people pointed out.

If that's the only concern, then how about

def chunkify(something, options={})
options={options=>true} unless options.kind_of(Hash)
....

end

options=:extra_fine ;=> :extra_fine
options={options=>true} unless options.kind_of?(Hash)
;=>{:extra_fine=>true}

Then your normal processing can continue.
 
M

Max Williams

options=:extra_fine ;=> :extra_fine
options={options=>true} unless options.kind_of?(Hash)
;=>{:extra_fine=>true}

Then your normal processing can continue.

OK, point taken :)

That's a nice snippet, thanks.

cheers all
max
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,265
Latest member
TodLarocca

Latest Threads

Top