Forum: Ruby learn to program

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Corey K. (Guest)
on 2006-05-16 02:04
I realy dont understand what Chris is talking about here in his book
"learning to program" Can someoe shed some light on this

def little_pest tough_var
tough_var = nil
puts ' HAHA! I ruined your variable!'
end

tough_var = ' You can\' t even touch my variable!'
little_pest tough_var
puts tough_var

output:
HAHA! I ruined your variable!
You can' t even touch my variable!

excerpt from his book:
In fact, two variables in that little program are named tough_var:
one inside little_pest and one outside of it. They donâ??t communicate.
They arenâ??t related. They arenâ??t even friends. When we called
little_pest tough_var, we really just passed the string from one
tough_var to the other (via the method call, the only way they can even
sort of communicate) so that both were pointing to the same string.
Then little_pest pointed its own local tough_var to nil, but that
did nothing to the tough_var variable outside the method.
Logan C. (Guest)
on 2006-05-16 03:31
(Received via mailing list)
On May 15, 2006, at 6:05 PM, corey konrad wrote:

> puts tough_var
> tough_var to the other (via the method call, the only way they can
> even
> sort of communicate) so that both were pointing to the same string.
> Then little_pest pointed its own local tough_var to nil, but that
> did nothing to the tough_var variable outside the method.
>
> --
> Posted via http://www.ruby-forum.com/.
>

It has to do with variable scoping. Try this metaphor on for size.

You have a stack of papers. When ever you call a function, you grab a
blank piece of paper. On it, you write the names and values for all
the variables in that function and you put it on top of the stack.
You then execute the code inside the function. Any code in the
function can only change the stuff written on the piece of paper at
the top of the stack. When the function finishes, we take it's piece
of paper off the top of the stack of papers and throw it away.

Ok so we have an initial piece of paper.

We write on it:
tough_var = ' You can\' t even touch my variable!'

then we call a function, little_pest. We grab a blank piece of paper
for little pest, and write on it
tough_var = ' You can\'t even touch my variable!'

we put it on top of the stack.

Then little_pest says to set tough_var to nil.

We look at our piece of paper on the top of the stack of papers,
scribble out tough_var and write
tough_var = nil

We then print the "HAHA!" message, and finish our function. Since we
are done with our function, we take the piece paper off the top of
the stack, crumple it up, and throw it away.

then we saee we must print tough_var. We look at the paaper on the
top of the stack to see what tough var means. Oh its a string with '
You can\'t touch my variable '. Ok, we print that.
Natevw (Guest)
on 2006-05-16 03:47
(Received via mailing list)
corey konrad wrote:
> puts tough_var
> tough_var to the other (via the method call, the only way they can even
> sort of communicate) so that both were pointing to the same string.
> Then little_pest pointed its own local tough_var to nil, but that
> did nothing to the tough_var variable outside the method.
>

Looks like he's trying to get at the "scope" of variables.

I think that his example might be more clearly written with parentheses:

[code]
1: def little_pest(tough_var)
2:  tough_var = nil
3:  puts ' HAHA! I ruined your variable!'
4: end
5:
6: tough_var = ' You can\' t even touch my variable!'
7: little_pest(tough_var)
8: puts tough_var
[/code]

Pay attention to 'tough_var' through the code, it actually refers to two
different variables:
1) in line 1, 'tough_var' is the name given to the one argument (~=input
value) that the little_pest function takes. It is a local variable.
   in line 2, this local variable is set to nil.

2) in line 6, a global variable named 'tough_var' is declared and set to
the "You can't touch..." line
    in line 7, little_pest is called with the value of the global
tough_var


So when tough_var is set to nil in line 2, all that is being set to nil
is the local variable named 'tough_var', not the variable from lines
6-8.


To the Ruby interpretter, the code might as well be written as:

1: def little_pest(var1)
2:  var1 = nil
3:  puts ' HAHA! I ruined your variable!'
4: end
5:
6: var2 = ' You can\' t even touch my variable!'
7: little_pest(var2)
8: puts var2



HTH...I'm just learning Ruby, so maybe somebody could correct the
details (passing by value,etc.)....but that's what the author is getting
at.



-natevw
Corey K. (Guest)
on 2006-05-16 04:27
oh ok he is just talking about variable scope it was kind of hard to
tell from his example for some resaon, i dont know i think i am going to
skip this learn to program book, this chris guy really doesnt know how
to explain things to a person with a beginner mind set. i also am having
problems running his code examples i really dont  understand how the
code below works but when i copy and paste it into the live ruby program
all it does is close the live ruby program and shuts it down.

def ask question
good_answer = false
while (not good_answer)
puts question
reply = gets.chomp.downcase
if (reply == ' yes' or reply == ' no' )
good_answer = true
if reply == ' yes'
answer = true
else
answer = false
end
else
puts ' Please answer "yes" or "no".'
end
end
answer # This is what we return (true or false).
end





Natevw wrote:
> corey konrad wrote:
>> puts tough_var
>> tough_var to the other (via the method call, the only way they can even
>> sort of communicate) so that both were pointing to the same string.
>> Then little_pest pointed its own local tough_var to nil, but that
>> did nothing to the tough_var variable outside the method.
>>
>
> Looks like he's trying to get at the "scope" of variables.
>
> I think that his example might be more clearly written with parentheses:
>
> [code]
> 1: def little_pest(tough_var)
> 2:  tough_var = nil
> 3:  puts ' HAHA! I ruined your variable!'
> 4: end
> 5:
> 6: tough_var = ' You can\' t even touch my variable!'
> 7: little_pest(tough_var)
> 8: puts tough_var
> [/code]
>
> Pay attention to 'tough_var' through the code, it actually refers to two
> different variables:
> 1) in line 1, 'tough_var' is the name given to the one argument (~=input
> value) that the little_pest function takes. It is a local variable.
>    in line 2, this local variable is set to nil.
>
> 2) in line 6, a global variable named 'tough_var' is declared and set to
> the "You can't touch..." line
>     in line 7, little_pest is called with the value of the global
> tough_var
>
>
> So when tough_var is set to nil in line 2, all that is being set to nil
> is the local variable named 'tough_var', not the variable from lines
> 6-8.
>
>
> To the Ruby interpretter, the code might as well be written as:
>
> 1: def little_pest(var1)
> 2:  var1 = nil
> 3:  puts ' HAHA! I ruined your variable!'
> 4: end
> 5:
> 6: var2 = ' You can\' t even touch my variable!'
> 7: little_pest(var2)
> 8: puts var2
>
>
>
> HTH...I'm just learning Ruby, so maybe somebody could correct the
> details (passing by value,etc.)....but that's what the author is getting
> at.
>
>
>
> -natevw
jake m (Guest)
on 2006-05-16 04:32
corey konrad wrote:
> oh ok he is just talking about variable scope it was kind of hard to
> tell from his example for some resaon, i dont know i think i am going to
> skip this learn to program book, this chris guy really doesnt know how
> to explain things to a person with a beginner mind set. i also am having
> problems running his code examples i really dont  understand how the
> code below works but when i copy and paste it into the live ruby program
> all it does is close the live ruby program and shuts it down.
>
> def ask question
> good_answer = false
> while (not good_answer)
> puts question
> reply = gets.chomp.downcase
> if (reply == ' yes' or reply == ' no' )
> good_answer = true
> if reply == ' yes'
> answer = true
> else
> answer = false
> end
> else
> puts ' Please answer "yes" or "no".'
> end
> end
> answer # This is what we return (true or false).
> end

Corey, that is the definition of a method. to get a result add something
like
                response = ask 'are you wearing a blue shirt'
                puts response
Corey K. (Guest)
on 2006-05-16 04:46
cant because live ruby irb closes completly when i enter that code. It
doesnt work.



jake m wrote:
> corey konrad wrote:
>> oh ok he is just talking about variable scope it was kind of hard to
>> tell from his example for some resaon, i dont know i think i am going to
>> skip this learn to program book, this chris guy really doesnt know how
>> to explain things to a person with a beginner mind set. i also am having
>> problems running his code examples i really dont  understand how the
>> code below works but when i copy and paste it into the live ruby program
>> all it does is close the live ruby program and shuts it down.
>>
>> def ask question
>> good_answer = false
>> while (not good_answer)
>> puts question
>> reply = gets.chomp.downcase
>> if (reply == ' yes' or reply == ' no' )
>> good_answer = true
>> if reply == ' yes'
>> answer = true
>> else
>> answer = false
>> end
>> else
>> puts ' Please answer "yes" or "no".'
>> end
>> end
>> answer # This is what we return (true or false).
>> end
>
> Corey, that is the definition of a method. to get a result add something
> like
>                 response = ask 'are you wearing a blue shirt'
>                 puts response
Eric A. (Guest)
on 2006-05-16 06:09
(Received via mailing list)
That's a nice little visualization trick. Did you
come up with that?
Natevw (Guest)
on 2006-05-16 06:24
(Received via mailing list)
corey konrad wrote:
> oh ok he is just talking about variable scope it was kind of hard to
> tell from his example for some resaon, i dont know i think i am going to
> skip this learn to program book, this chris guy really doesnt know how
> to explain things to a person with a beginner mind set.

 From what I've seen so far, I think you could find better.


> if (reply == ' yes' or reply == ' no' )
> answer # This is what we return (true or false).
> end
>

This pastes fine into my version of 'irb'.
You seem to have a couple of extra spaces, but that shouldn't close the
program.

Does the author really not indent his examples? If so that's another
reason to find a better book.

Here it is indented, that might help you understand it.

def ask question
  good_answer = false
  while (not good_answer)
   puts question
   reply = gets.chomp.downcase
   if (reply == 'yes' or reply == 'no' )
    good_answer = true
    if reply == 'yes'
	answer = true
    else
	answer = false
    end
    else
     puts ' Please answer "yes" or "no".'
   end
  end
  answer # This is what we return (true or false).
end
answer = ask "Is this working?"


(keep scope in mind for the last 'answer')


It seems that your beginner guide is a bit too "friendly" and keeps you
from important details that you'll need to learn soon anyway.

Have you looked at the "Programming Ruby" book? I had plenty of
programming experience before going to it, so YMMV, but it at least
keeps things concise. Try the 1st edition on for size here:
http://www.rubycentral.com/book/intro.html

I'd recommend looking for a book that's understandable, but doesn't
fudge the details. Otherwise, my method of choice is to learn a bit,
then try writing things on my own, which always forms questions, which
leads to more searching/reading/learning.

-natevw
Logan C. (Guest)
on 2006-05-16 11:59
(Received via mailing list)
On May 15, 2006, at 10:08 PM, Eric A. wrote:

>>> puts ' HAHA! I ruined your variable!'
>>> excerpt from his book:
>>>
>> it away.
>> tough_var = nil
>> We then print the "HAHA!" message, and finish our function. Since
>> we are done with our function, we take the piece paper off the top
>> of the stack, crumple it up, and throw it away.
>> then we saee we must print tough_var. We look at the paaper on the
>> top of the stack to see what tough var means. Oh its a string with
>> ' You can\'t touch my variable '. Ok, we print that.
>

Well in this case yeah. But I imagine that's what the first guy who
thought of a call stack was thinking of anyway.
Pat M. (Guest)
on 2006-05-16 12:45
(Received via mailing list)
On 5/15/06, corey konrad <removed_email_address@domain.invalid> wrote:
> excerpt from his book:
> In fact, two variables in that little program are named tough_var:
> one inside little_pest and one outside of it. They don't communicate.
> They aren't related. They aren't even friends. When we called
> little_pest tough_var, we really just passed the string from one
> tough_var to the other (via the method call, the only way they can even
> sort of communicate) so that both were pointing to the same string.
> Then little_pest pointed its own local tough_var to nil, but that
> did nothing to the tough_var variable outside the method.

Here's something that's bothered the hell out of me.  Can someone
please explain it to me?

def major_pest(wussy_var)
  wussy_var.slice!(0..-1)
  puts "HAHA! I ruined your variable!"
end

wuss_var = "I'm about to get owned"
major_pest wuss_var
puts wuss_var

wuss_var is "" after major_pest returns.  So apparently you can affect
it.  The only way (that I know of) to write that method without
affecting the outside variable is

def major_pest(wussy_var)
  guardian_angel = wussy_var.clone
  guardian_angel.slice!(0..-1)
  puts "HAHA! I ruined your variable!"
end

Anyway I guess that example merely serves to show method scope?
Changing the variable named tough_var inside the method doesn't do
anything to the one outside the method.  The object that tough_var
points to inside the method is the same object that the external
tough_var points to, so when you modify the object inside the method,
those changes are seen outside of it as well.

Pat
Tim B. (Guest)
on 2006-05-16 13:01
(Received via mailing list)
> wuss_var is "" after major_pest returns.  So apparently you can affect
> it.  The only way (that I know of) to write that method without
> affecting the outside variable is
>
> def major_pest(wussy_var)
>   guardian_angel = wussy_var.clone
>   guardian_angel.slice!(0..-1)
>   puts "HAHA! I ruined your variable!"
> end

the reason that ruins your variable is that `slice!` modifies the
object in place (this is why it ends in an `!`).  If you do:

> def major_pest(wussy_var)
>   wussy_var=wussy_var.slice(0..-1)
>   puts "HAHA! I ruined your variable!"
> end

instead you don't change the original object, instead slice creates
the clone for you.
   -tim
Pat M. (Guest)
on 2006-05-16 13:17
(Received via mailing list)
On 5/16/06, Tim B. <removed_email_address@domain.invalid> wrote:
> the reason that ruins your variable is that `slice!` modifies the
> object in place (this is why it ends in an `!`).

I understand that...what I don't necessarily understand is why
wuss_var is "" outside of the method.  If they really have no
interaction, then I wouldn't expect it to change.


If you do:
>
> > def major_pest(wussy_var)
> >   wussy_var=wussy_var.slice(0..-1)
> >   puts "HAHA! I ruined your variable!"
> > end
>
> instead you don't change the original object, instead slice creates
> the clone for you.

My real issue is with the excerpt from the book, which would make new
programmers think they can do whatever they want to an object inside a
method and not have it affect anything outside of it.  Clearly that is
not the case.

Pat
Tim B. (Guest)
on 2006-05-16 15:37
(Received via mailing list)
> My real issue is with the excerpt from the book, which would make new
> programmers think they can do whatever they want to an object inside a
> method and not have it affect anything outside of it.  Clearly that is
> not the case.

The book is trying to make a point which is really important and
central to programming. It's difficult to explain, but once it
"clicks" it seems trivial: the variable and the actual object the
variable points at are completely distinct.

Manipulating the variable doesn't change the object it points to, it
just makes the variable point to a different object:

  a = "Some object"	# `a` now points at "Some object"
  b=a 			# `b` now also point at "Some object"
  a = nil 		# `a` now points at nil, but this doesn't change "Some
object"

if you'd do this:

  a = a.upcase

`a` now points at the new Object returns by calling the `upcase`
method, i.e. you've changed the location that `a` points to.

Had you done this:
  a.upcase!

this would have changed the object that `a` is pointing at instead of
changing what the variable points at.
   -tim
Randy K. (Guest)
on 2006-05-16 17:36
(Received via mailing list)
On Monday 15 May 2006 07:29 pm, Logan C. wrote:
> It has to do with variable scoping. Try this metaphor on for size.

Very helpful, thanks!

Randy K. (not the OP)
This topic is locked and can not be replied to.