Variable scopes with code blocks

Hello!

Novice here. I’m reading Beginning Ruby and Beginning Rails by Apres and
building both applications they walk you through. Additionally, I’m
taking courses at lynda dot com and attempting to build a simple
application myself.

That said, I’m aware of the limits you have with local variable being
incapable of accessing variables defined inside of a code block, but is
there any exception to this rule?

Example:


1.times do
File.open(“text.txt”).each {|a| puts a}
end

puts a

This where I get my error.


Is there anything I can do to ‘puts a’ that will allow it to return the
content it was passed inside of the code block?

Ultimately, I’d like to store the ‘text.txt’ as an array so I can call
.uniq! on it… But we don’t need to get into that in this thread.

I hope my question makes sense.

Thank you in advanced,
Aaron

Good afternoon,

…this is slightly off topic, but i’m also going thru the Apress
“Beginning
Ruby” book…i’m finding it to be a really good read…
…are you using a Mac, if so, take a look at ‘TextMate’ the editor
recommended for the Mac - it’s excellent and it doesn’t cost much…it
supports both Ruby and Rails…
…i went thru the AWDWR [“Agile Web Devlopment with Rails”] book - but
I
found the “Ruby on Rails 3 Tutorial” with an associated screen cast to
be
better suited to me…it’s a bit expensive, the screen cast and book
will
run about $100…

…i’m in chapter 3 with the “Beginning Ruby” book and I hope to finish
it
on Wednesday and then get back to Rails…

…i’ll take a look at your question on Tuesday…

Good weekend

----- Original Message -----
From: “Patrick L.” [email protected]
To: “ruby-talk ML” [email protected]
Sent: Friday, May 27, 2011 6:22 PM
Subject: Variable scopes with code blocks.

Hey Patrick,

I too am really enjoying Beginning Ruby and TextMate is awesome! I
currently prefer Coda for HTML and CSS, but TextMate has been very
enjoyable while working with Ruby.

I just started Chapter 3 of Beginning Ruby this week. I plan on
finishing it over the holiday weekend, so we can discuss what we’ve
gathered on Wednesday. I encourage you to check our “Rails for
Zombies”. Just google it and sign up for the free course.

On Sat, May 28, 2011 at 12:22 AM, Patrick L.
[email protected] wrote:

Hello!

That said, I’m aware of the limits you have with local variable being
incapable of accessing variables defined inside of a code block, but is
there any exception to this rule?

What you can do is declaring the variable before the block, and access
it within the block. Like so:

a = [] # Let’s store data in an array
(1…3).each do |i|
?> a << i # We append the index i to the array
end
=> 1…3
puts a # Now contains [1, 2, 3].


Phillip G.

A method of solution is perfect if we can forsee from the start,
and even prove, that following that method we shall attain our aim.
– Leibnitz

On 05/27/2011 03:22 PM, Patrick L. wrote:

In light of your ultimate goal, consider using
File.readlines(“text.txt”) [1].

Also note that in your example you are opening the file without ever
closing it. If you pass a block to File.open(), it will ensure the file
is closed [2].

[1] http://rdoc.info/stdlib/core/1.9.2/IO.readlines
[2] http://rdoc.info/stdlib/core/1.9.2/File.open

-Justin

Justin,

Thanks for the input.

If you pass a block to File.open(), it will ensure the file
is closed [2].

What is the importance of having the program close the text file? Is it
still ideal if you wish to revisit the same text file later in the
script?

Aaron

On Sat, May 28, 2011 at 4:14 AM, Justin C. [email protected]
wrote:

incapable of accessing variables defined inside of a code block, but is

This where I get my error.


Is there anything I can do to ‘puts a’ that will allow it to return the
content it was passed inside of the code block?

Ultimately, I’d like to store the ‘text.txt’ as an array so I can call
.uniq! on it… But we don’t need to get into that in this thread.

In light of your ultimate goal, consider using File.readlines(“text.txt”)
[1].

Or rather File.foreach. File.readlines should only be used if you
need all lines of the file in memory for example because you need to
go through them multiple times and you know the file is not too large.
For making lines unique there are different options available
depending on the fact whether the order is important.

I find the first one the most elegant:

order doesn’t matter && we are on 1.9

require ‘set’
unique = File.foreach(“text.txt”).to_set

order does matter or on 1.8.6 or earlier

require ‘set’
set = Set.new
unique = []
File.foreach(“text.txt”) {|l| unique << l if set.add? l}

Or, a bit more involved:

h = Hash.new []
File.foreach(“setup.log”) {|l| h.fetch(l) {h[l] = h.default << l}}
unique = h.default

You can also use a variant of what I once proposed:
http://viewsourcecode.org/why/redhanded/bits/klemmeSSilentHash.html

h = {}
unique = File.foreach(“text.txt”).inject([]) {|a,line| h[line] ||= a <<
line}

Also note that in your example you are opening the file without ever closing
it. If you pass a block to File.open(), it will ensure the file is closed
[2].

+1!

[1] http://rdoc.info/stdlib/core/1.9.2/IO.readlines
[2] http://rdoc.info/stdlib/core/1.9.2/File.open

Cheers

robert