# Blocks and local variable creation

**URL:** <https://www.ruby-forum.com/t/blocks-and-local-variable-creation/186993>\
**Category:** Ruby\
**Created:** [April 15, 2010, 12:17pm UTC](https://www.ruby-forum.com/t/blocks-and-local-variable-creation/186993 "2010-04-15T12:17:44Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![johnlester](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@johnlester](https://www.ruby-forum.com/u/johnlester)\
**Post date:** [April 15, 2010, 12:17pm UTC](https://www.ruby-forum.com/t/blocks-and-local-variable-creation/186993/1 "2010-04-15T12:17:44Z")

</div>

Hello,

I have a simple method:

def rights\_for\_item (rights\_hash, item)  
rights\_hash.each { |k,v| (rights ||= []) \<\< k if v.include? item }  
rights  
end

This does not work because “rights” is created local to the block on  
“rights\_hash.each” instead of local to the method itself. This makes the  
statement returning the value of “rights” to fail because there is no  
method local variable called “rights”.

I can do this instead

def rights\_for\_item (rights\_hash, item)  
rights = Array.new  
rights\_hash.each { |k,v| rights \<\< k if v.include? item }  
rights  
end

The problem is this returns an empty array rather than nil if no matches  
are found. So I do this:

def rights\_for\_item (rights\_hash, item)  
rights = Array.new  
rights\_hash.each { |k,v| rights \<\< k if v.include? item }  
rights.empty? ? rights : nil  
end

But I don’t think it is good idiomatic ruby code. Is there a better way  
to write this type of thing ?

---

<div class="post-metadata">

**Author:** ![johnlester](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@johnlester](https://www.ruby-forum.com/u/johnlester)\
**Post date:** [April 15, 2010, 4:17pm UTC](https://www.ruby-forum.com/t/blocks-and-local-variable-creation/186993/2 "2010-04-15T16:17:08Z")

</div>

John L. wrote:

> I have a simple method:
> 
> def rights\_for\_item (rights\_hash, item)  
> rights\_hash.each { |k,v| (rights ||= []) \<\< k if v.include? item }  
> rights  
> end
> 
> This does not work because “rights” is created local to the block on  
> “rights\_hash.each” instead of local to the method itself.

Just prepare it outside the block first:

def rights\_for\_item(…)  
rights = nil  
rights\_hash.each { … }  
rights  
end

> But I don’t think it is good idiomatic ruby code. Is there a better way  
> to write this type of thing ?

It’s arguably more idiomatic to return an empty array than to return  
nil. It’s more consistent from the user’s point of view. e.g. they can  
do

if rights\_for\_item(x).include? “update”  
… do something  
end

If there is a possibility of returning nil then it is more awkward:

r = rights\_for\_item(x)  
if r && r.include? “update”  
… do something  
end

---

<div class="post-metadata">

**Author:** ![johnlester](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@johnlester](https://www.ruby-forum.com/u/johnlester)\
**Post date:** [April 15, 2010, 5:06pm UTC](https://www.ruby-forum.com/t/blocks-and-local-variable-creation/186993/3 "2010-04-15T17:06:02Z")

</div>

On Thu, Apr 15, 2010 at 12:17 PM, John L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Hello,

> But I don’t think it is good idiomatic ruby code. Is there a better way  
> to write this type of thing ?

I do not reallly understand why you want nil, instead of [], but apart  
of this I would do  
select{|\_,v| v.include? item}.map(&:first)

or if you insist

inject( nil ){ |r,(k,v)| v.include?( item ) ? (r||[]) \<\< k : r }

---

<div class="post-metadata">

**Author:** ![johnlester](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@johnlester](https://www.ruby-forum.com/u/johnlester)\
**Post date:** [April 16, 2010, 11:21am UTC](https://www.ruby-forum.com/t/blocks-and-local-variable-creation/186993/4 "2010-04-16T11:21:10Z")

</div>

Robert D. wrote:

> I do not reallly understand why you want nil, instead of [], but apart  
> of this I would do  
> select{|\_,v| v.include? item}.map(&:first)
> 
> or if you insist
> 
> inject( nil ){ |r,(k,v)| v.include?( item ) ? (r||[]) \<\< k : r }

Can you please explain the line:

> select{|\_,v| v.include? item}.map(&:first)

I’ve never seen the \_ before where I would expect a variable. I also  
don’t understand (&:first) on the call to map.

The reason I was returning nil was so I can the write code like this:

rights\_held = rights\_for\_item (rights\_hash, item)  
perform\_something\_with\_rights unless rights\_hash.nil?

perhaps I should change that thought process to this:

rights\_held = rights\_for\_item (rights\_hash, item)  
perform\_something\_with\_rights unless rights\_hash.empty?

I had thought use of nil was the right way but I’m learning so I’m happy  
to be convinced otherwise…

---

<div class="post-metadata">

**Author:** ![johnlester](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@johnlester](https://www.ruby-forum.com/u/johnlester)\
**Post date:** [April 15, 2010, 4:20pm UTC](https://www.ruby-forum.com/t/blocks-and-local-variable-creation/186993/5 "2010-04-15T16:20:56Z")

</div>

On Apr 15, 6:17 am, John L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> “rights\_hash.each” instead of local to the method itself. This makes the
> 
> ## to write this type of thing ?
> 
> Posted viahttp://www.ruby-forum.com/.

Hash has a select method, in 1.8 (at least according to the docs) it  
will a return an array of key,value pairs, in 1.9 it creates a hash  
with the selected key,value pairs  
You can use the keys method to get the key values as an array

Rather than have the method return two different types (array or nil)  
why not accept an empty array as the valid indication of no rights?

Cheers

---

<div class="post-metadata">

**Author:** ![johnlester](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@johnlester](https://www.ruby-forum.com/u/johnlester)\
**Post date:** [April 16, 2010, 11:41am UTC](https://www.ruby-forum.com/t/blocks-and-local-variable-creation/186993/6 "2010-04-16T11:41:24Z")

</div>

On Fri, Apr 16, 2010 at 11:21 AM, John L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Can you please explain the line:
> 
> > select{|\_,v| v.include? item}.map(&:first)
> 
> I’ve never seen the \_ before where I would expect a variable.

It’s a regular variable name. A block can receive several parameters:

select {|k,v| v.include? item}

It’s a convention that indicates that you are not interested in using  
that variable.

> I also  
> don’t understand (&:first) on the call to map.

Search google for Symbol#to\_proc, there are many explanations out  
there that are better than what I would be able to explain (in few  
words: Ruby tries to convert and object to a proc when you use it like  
this, calling the to\_proc method).

> I had thought use of nil was the right way but I’m learning so I’m happy  
> to be convinced otherwise…

Others have already talked about this, and I agree it’s better to  
return the same type of object from a method, and nil and an array are  
different types. Don’t know how to convince you :-).

Jesus.

---

<div class="post-metadata">

**Author:** ![johnlester](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@johnlester](https://www.ruby-forum.com/u/johnlester)\
**Post date:** [April 16, 2010, 4:50pm UTC](https://www.ruby-forum.com/t/blocks-and-local-variable-creation/186993/7 "2010-04-16T16:50:00Z")

</div>

On Fri, Apr 16, 2010 at 5:21 AM, John L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> The reason I was returning nil was so I can the write code like this:
> 
> rights\_held = rights\_for\_item (rights\_hash, item)  
> perform\_something\_with\_rights unless rights\_hash.nil?

I think you meant rights\_held instead of rights\_hash in that second  
line.

> perhaps I should change that thought process to this:
> 
> rights\_held = rights\_for\_item (rights\_hash, item)  
> perform\_something\_with\_rights unless rights\_hash.empty?

My inclination would be to do something like

perform\_something\_with\_rights(rights\_for\_item(rights\_hash, item))

Let the thing which needs the rights deal with what rights it has, and  
an empty collection(array) of rights seems a better representation of  
empty rights than nil.

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Github: [rubyredrick (Rick DeNatale) · GitHub](http://github.com/rubyredrick)  
Twitter: @RickDeNatale  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![johnlester](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@johnlester](https://www.ruby-forum.com/u/johnlester)\
**Post date:** [April 17, 2010, 12:30am UTC](https://www.ruby-forum.com/t/blocks-and-local-variable-creation/186993/8 "2010-04-17T00:30:14Z")

</div>

On Fri, Apr 16, 2010 at 6:09 PM, John L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> I found the explanation from Jesus about (&:first) very interesting but  
> I’m not sure I think it improves readability. I read these:  
> [http://pragdave.pragprog.com/pragdave/2005/11/symbolto\_proc.html](http://pragdave.pragprog.com/pragdave/2005/11/symbolto_proc.html)  
> [Symbol.to\_proc is way slower than invoking methods directly - Rails - Ruby-Forum](http://www.ruby-forum.com/topic/161089)
> 
> Personally I think the Symbol#to\_proc approach is less idomatic than the  
> long hand version but I guess it’s a matter of personal taste.

Actually, given the definition of idiom, I’d argue that it’s MORE  
idiomatic.

The Symbol#to\_proc idea has been around ruby for quite a while. It  
got picked up in Rails some time ago, and is popular in the rails  
community despite a certain cost in performance which I believe has  
been ameliorated in Ruby 1.9 which made it part of the core.

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Github: [rubyredrick (Rick DeNatale) · GitHub](http://github.com/rubyredrick)  
Twitter: @RickDeNatale  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![johnlester](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@johnlester](https://www.ruby-forum.com/u/johnlester)\
**Post date:** [April 17, 2010, 12:09am UTC](https://www.ruby-forum.com/t/blocks-and-local-variable-creation/186993/9 "2010-04-17T00:09:22Z")

</div>

Rick Denatale wrote:

> I think you meant rights\_held instead of rights\_hash in that second  
> line.

Yes I did’ Serves me right for doing two things at once 😉

> My inclination would be to do something like
> 
> perform\_something\_with\_rights(rights\_for\_item(rights\_hash, item))
> 
> Let the thing which needs the rights deal with what rights it has, and  
> an empty collection(array) of rights seems a better representation of  
> empty rights than nil.

Yes, I agree. I’m convinced of the argument for returning the same type.  
Makes a lot of sense when you come to think of it.

I found the explanation from Jesus about (&:first) very interesting but  
I’m not sure I think it improves readability. I read these:  
[http://pragdave.pragprog.com/pragdave/2005/11/symbolto\_proc.html](http://pragdave.pragprog.com/pragdave/2005/11/symbolto_proc.html)  
[http://www.ruby-forum.com/topic/161089](http://www.ruby-forum.com/topic/161089)

Personally I think the Symbol#to\_proc approach is less idomatic than the  
long hand version but I guess it’s a matter of personal taste.
