Instance variable in pseudo-global scope

As I understand things:

  • Variables whose names have no leading sigil have local scope.

  • Instance variables are local scope for the particular instance of a
    class within which they “live”.

  • A Ruby program’s “global” scope is actually the scope of an instance
    of
    Object (or, under certain circumstances, maybe it could be an instance
    of something further down the class inheritance hierarchy . . . ?).

As such, it seems that within your program’s “global” scope (not truly
global, but close enough for government work in most cases), the
effective difference between variables named foo and @foo is nothing but
one character. Is there some technical difference that might have an
effect on the “behavior”[0] of the code I write, as long as neither of
them is being exported to some other running code or enclosed in a more
restricted scope within my program?

NOTES

[0]: Someone actually flamed me for referring to the “behavior” of some
code, once upon a time – thus the scare quotes around behavior in this
case.

On Jun 1, 2011, at 10:01 , Chad P. wrote:

As such, it seems that within your program’s “global” scope (not truly
global, but close enough for government work in most cases), the
effective difference between variables named foo and @foo is nothing but
one character. Is there some technical difference that might have an
effect on the “behavior”[0] of the code I write, as long as neither of
them is being exported to some other running code or enclosed in a more
restricted scope within my program?

The variable lookup code will go through different internal paths, but
given your restrictions shouldn’t have different behavior at all.

On Wed, Jun 1, 2011 at 6:01 PM, Chad P. [email protected] wrote:

[0]: Someone actually flamed me for referring to the “behavior” of some
code, once upon a time – thus the scare quotes around behavior in this
case.


Chad P. [ original content licensed OWL: http://owl.apotheon.org ]

Well, @vars in main are visible to methods defined in main. For example:

@foo = 1
foo = 1

def bar
@foo = 10
end

def baz
foo = 10
end

bar
baz

p @foo # => 10
p foo # => 2

Is that the kind of difference you’re interested in?

Regards,
Sean

On Wed, Jun 1, 2011 at 2:37 PM, Sean O’Halpin
[email protected]wrote:

of something further down the class inheritance hierarchy . . . ?).

@foo = 1
bar

You will get 10 and 1 as output, not 10 and 2.

I think everyone knows how the local var works, so it’s not that
interesting. I think what is much more interesting is the instance var
will
change depending on who invokes the foo method.

@foo = 1

def bar
@foo = 10
end

class C
@foo # => nil # !> instance variable @foo not initialized
bar
@foo # => 10
end

@foo # => 1

So no, its not that global. But TBH, I’m not sure how I feel about
defining
methods and instance vars in main, there are a number of quirky
behaviours
like this. I I’ve started to opt for defining them on main’s
singleton_class, unless I really do want them to be “global”, which, on
any
decently sized project, isn’t very common.

On Thu, Jun 02, 2011 at 04:37:00AM +0900, Sean O’Halpin wrote:

Well, @vars in main are visible to methods defined in main. For example:

. . .

Is that the kind of difference you’re interested in?

Yes, it is. Evidently, instance variables are lexical scope,
which really should have occurred to me based on the fact I have
actually
made use of that fact in the past. Thank you.

On Thu, Jun 2, 2011 at 12:16 AM, Josh C. [email protected]
wrote:
[snip]

You will get 10 and 1 as output, not 10 and 2.

Thanks for pointing out that silly mistake. But the point remains the
same.

Regards,
Sean

Josh C. wrote in post #1002660:

@foo = 1

def bar
@foo = 10
end

class C
@foo # => nil # !> instance variable @foo not initialized
bar
@foo # => 10
end

@foo # => 1

And this is my explanation of that. The word ‘class’ starts a new
scope, cutting off the visibility of variables in an outer scope(except
global variables), so the toplevel @foo is no longer relevant inside the
class.

  1. Inside a class and outside any method definitions self = the class,
    so in this case self = C.
    2)Instance variables attach themselves to whatever is self.

As a result, the @foo on the first line of C attaches itself to
self(=C), and becomes what’s called a “class instance variable”.

Aside===
The “class instance variable” @foo can be accessed outside C by writing
C.foo–assumning you have defined an accessor method, which can be done
by adding the folloing to C:

class C
class <<self
attr_accessor :foo
end

end

  1. A top level def becomes a private method of Object, and as such it
    can be called by any object–but as with all private methods it must be
    called without a receiver.

The method call bar inside class C is implicitly the method call
self.bar, and because self=C, that is equivalent to C.bar, which means
that inside bar self = C, so any instance variables mentioned inside bar
are instance variables of C. Assigning 10 to @foo means you are
assigning 10 to C’s “class instance variable” @foo.

When the class ends, you exit back into the toplevel, and @foo is the
toplevel @foo.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs