New to Ruby - Scope Question

x = 10
y = 5

def square(x)
puts "within the method x is " + x.to_s
puts x*x
end

In the above when defining the method, the x that is being referenced in
“x.to_s” and puts x*x is by default the variable x, defined above, with
a value of 10, correct? This then means that even though this variable
isn’t defined within the method it can still be called on from outside
the code. However, if the variable was given a value within the method
then it wouldn’t be available outside of the method, correct?

Can someone explain why this is so. I guess I don’t NEED to know why,
but I’d like to understand it a bit better if possible. Thanks!

On Jun 21, 2012, at 12:39 AM, Emeka P. wrote:

x = 10
y = 5

def square(x)
puts "within the method x is " + x.to_s
puts x*x
end

Here, you define method square but do not invoke it yet. ‘x’ here is a
method parameter that will take the value provided in a method
invocation. It does not have anything to do with ‘x’ in ‘x = 10’.

For example, when you invoke this method as:
square(25)

x in x.to_s and x*x will be 25. And outer scope x will still be 10 after
the method returns.

Gennady.

On Thursday 21 June 2012 Emeka P. wrote

“x.to_s” and puts x*x is by default the variable x, defined above, with
a value of 10, correct? This then means that even though this variable
isn’t defined within the method it can still be called on from outside
the code. However, if the variable was given a value within the method
then it wouldn’t be available outside of the method, correct?

Can someone explain why this is so. I guess I don’t NEED to know why,
but I’d like to understand it a bit better if possible. Thanks!


Posted via http://www.ruby-forum.com/.

No, the x being referred to in the “x.to_s” expression is not the one
you set
to 10 but the one you gave as argument to the square method.

When you define a method, you create a new scope. This means that local
variables defined outside the method won’t be availlable inside the
method
body. Also, local variables defined inside the method body (including
the
arguments of the method) won’t be availlable outside the method itself.

On the other hand, when you define a method which takes some arguments,
you
implicitly introduce a local variable for each argument in the scope of
the
method body. When the method is called, this variables will be given the
values you pass as arguments to the method call.

All this means that your method would work exactly in the same way even
if you
called the argument with another name (provided, of course, that you
change
all references to it to use the new name). For example:

def square(z)
puts "within the method z is " + z.to_s
puts z*z
end

I hope this helps

Stefano

Hi,

Emeka P. wrote in post #1065478:

Can someone explain why this is so. I guess I don’t NEED to know why,
but I’d like to understand it a bit better if possible. Thanks!

The question has already been answered, but you can actually try out
things like that yourself:

x = 123
def f()
puts x
end
f()

Since you get an error for an undefined local variable or method, Ruby’s
methods obviously don’t see outer variables.

And for the other question:

def g()
a = 123
end
g()
puts a

Again you get an error. So this doesn’t work either.

Hi Stefano & Gennady,

Thanks for writing back and for your explanations.

I just looked over what I wrote and figured out what happened. When I
was playing around with this in IRB, I accidentally set both x and y to
have a value of 10 so when I ran the method square with the argument y,
I got the same results as I got for argument x and got really confused
about local variable scope.

Thanks again for taking the time to explain, would have walked away with
some seriously misguided understanding of local variables.

Stefano C. wrote in post #1065482:

On Thursday 21 June 2012 Emeka P. wrote

“x.to_s” and puts x*x is by default the variable x, defined above, with
a value of 10, correct? This then means that even though this variable
isn’t defined within the method it can still be called on from outside
the code. However, if the variable was given a value within the method
then it wouldn’t be available outside of the method, correct?

Can someone explain why this is so. I guess I don’t NEED to know why,
but I’d like to understand it a bit better if possible. Thanks!


Posted via http://www.ruby-forum.com/.

No, the x being referred to in the “x.to_s” expression is not the one
you set
to 10 but the one you gave as argument to the square method.

When you define a method, you create a new scope. This means that local
variables defined outside the method won’t be availlable inside the
method
body. Also, local variables defined inside the method body (including
the
arguments of the method) won’t be availlable outside the method itself.

On the other hand, when you define a method which takes some arguments,
you
implicitly introduce a local variable for each argument in the scope of
the
method body. When the method is called, this variables will be given the
values you pass as arguments to the method call.

All this means that your method would work exactly in the same way even
if you
called the argument with another name (provided, of course, that you
change
all references to it to use the new name). For example:

def square(z)
puts "within the method z is " + z.to_s
puts z*z
end

I hope this helps

Stefano

Thanks for getting back to me as well Jan. Was using Sublime Text 2 and
doing builds in that after entering code, but recently switched over to
trying to do more via IRB, which I feel is giving me a deeper
understanding, but I seem to be making more mistakes in. Going to step
up my meticulousness!

Jan E. wrote in post #1065483:

Hi,

Emeka P. wrote in post #1065478:

Can someone explain why this is so. I guess I don’t NEED to know why,
but I’d like to understand it a bit better if possible. Thanks!

The question has already been answered, but you can actually try out
things like that yourself:

x = 123
def f()
puts x
end
f()

Since you get an error for an undefined local variable or method, Ruby’s
methods obviously don’t see outer variables.

And for the other question:

def g()
a = 123
end
g()
puts a

Again you get an error. So this doesn’t work either.