# Question about passing hashes to an action

**URL:** <https://www.ruby-forum.com/t/question-about-passing-hashes-to-an-action/109146>\
**Category:** Ruby\
**Created:** [July 11, 2007, 9:53pm UTC](https://www.ruby-forum.com/t/question-about-passing-hashes-to-an-action/109146 "2007-07-11T21:53:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [July 11, 2007, 9:53pm UTC](https://www.ruby-forum.com/t/question-about-passing-hashes-to-an-action/109146/1 "2007-07-11T21:53:45Z")

</div>

It seems to be a common tactic in ruby to pash what looks like a  
key-value pair, in which the key is a symbol, to an action. For example  
with the rails action ‘render’, we say

render :text =\> “Hello world!” #(from dhh’s famous blog tutorial)

Can anyone explain to me what’s happening here, ie what’s being passed  
in? Is it the equivalent of having a (say) java method that takes a  
string and saying  
render(“Hello world!”)?

I’ve been trying to experiment with my own classes with this tactic, but  
i’m new to ruby and can’t get an example of the above working.

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [July 11, 2007, 10:38pm UTC](https://www.ruby-forum.com/t/question-about-passing-hashes-to-an-action/109146/2 "2007-07-11T22:38:30Z")

</div>

Alle mercoledÃ¬ 11 luglio 2007, Max W. ha scritto:

> I’ve been trying to experiment with my own classes with this tactic, but  
> i’m new to ruby and can’t get an example of the above working.

What is happening here is that you’re calling the method render passing  
an  
hash as argument. In ruby, when you pass an hash as the last argument to  
a  
method, you may omit the usual braces, so the line you quoted is the  
same as:

render( {:text =\> “Hello world!” } )

Usually, this is used to fake keyword arguments, which ruby doesn’t  
have.  
As an example, imagine you want to write a method which takes a string  
and  
does some of the following things:

- remove whitespace at the left, right or both
- makes the string downcase or upcase
- crypt it  
You want the user to decide which of the previous transformation he  
wants to  
perform (of course, this is only an example; in reality, it might be  
better  
to create three separate methods). The method can be written this way:

def transform\_string(orig, actions = nil ) #1  
default = { :remove\_whitespace=\>:both, :change\_case=\>nil, :crypt =\>  
nil} #2  
acts = actions || default  
temp = orig.dup #3

if acts[:remove\_whitespace] then #4  
case acts[:remove\_whitespace] #5  
when :left then temp.lstrip! #6  
when :right then temp.rstrip! #7  
when :left\_right then temp.strip! #8  
end #9  
end #10

if acts[:change\_case] == :downcase then temp.downcase! #11  
elsif acts[:change\_case] == :upcase then temp.upcase! #12  
end #13

temp = temp.crypt(acts[:crypt]) if acts[:crypt] #14  
temp #15  
end #16

In line 1, we define a method which takes a mandatory argument, the  
string  
modify, and an optional argument, a hash where the user will specify  
which  
actions he wants to perform.

In line 2, we create an hash with the default actions (the actions to  
perform  
if the user didn’t pass the optional argument). This hash contains three  
entries, two of which are nil. The only non-nil one is  
:remove\_whitespace,  
with content :both. Since actions whose value is nil won’t be carried  
out,  
this means that, if the user didn’t specify an action, the method will  
remove  
the whitespace both the left and the right of the string (the value  
corresponding to :remove\_whitespace in the hash is :both). In line 3, we  
assign to the variable acts the hash containing the action specified by  
the  
user or, if this is nil (i.e, the user didn’t specify any action), the  
hash  
with the default actions.

In lines 4-10, depending on the content of the :remove\_whitespace entry  
of  
acts, we remove the whitespace from the left, right, left and right of  
the  
string, or we leave it unchanged.

Likewise, in lines 11-13, if the action :change\_case was specified, the  
case  
of the string is changed and, in line 14 we crypt the string if it was  
requested.

NOTE  
In this example, the hash with the default actions wasn’t used if the  
user  
specified the second parameter to the method. Often, you’ll need to keep  
the  
default values for the keys the user doesn’t specify. In this case, you  
can  
do the following:

def my\_method( hash = {} )  
default\_hash = { :opt\_a =\> value\_a, :opt\_b =\> value\_b }  
options = default\_hash.merge(hash)  
#…  
end

Here, the values to be used are obtained by merging the hash with the  
default  
options with the one passed as argument. This will overwrite the  
elements in  
default\_hash which are also in hash, leaving the others unchanged.

I hope this helps

Stefano

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [July 11, 2007, 10:40pm UTC](https://www.ruby-forum.com/t/question-about-passing-hashes-to-an-action/109146/3 "2007-07-11T22:40:31Z")

</div>

On Jul 11, 2007, at 3:53 PM, Max W. wrote:

> render(“Hello world!”)?
> 
> I’ve been trying to experiment with my own classes with this  
> tactic, but  
> i’m new to ruby and can’t get an example of the above working.

The trailing set of key =\> value pairs are turned into a hash passed  
as the final argument to a method. The fully punctuated version of  
that is:

render({:text =\> “Hello world!”})

You’ll often see methods defined as:

def my\_method(arg1, arg2, options={})

when there is an optional set of options that can be passed in as a  
hash.

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [July 12, 2007, 1:03am UTC](https://www.ruby-forum.com/t/question-about-passing-hashes-to-an-action/109146/4 "2007-07-12T01:03:45Z")

</div>

That’s an excellent and extremely illuminating explanation Stefano!  
Thanks very much, you’re a gent.

> I hope this helps
> 
> Stefano
