Jacob Fugal
11/16/2006 4:54:00 PM
On 11/16/06, Nia <badluck105@yahoo.com> wrote:
> so is it wrong to declare a
> variable outside a method? cause i usually do that a lot,
This misunderstanding probably stems from the following type of code:
# NOTE: no enclosing class
@a = "foo" # (a)
def bar
puts @a # (b)
end
bar # => prints "foo"
Se *here*, the @a seems to be able to stretch across the method definition. Why?
The reason is because all "procedural" (top level scope) code is
invoked in the context of the "main" object. At (a), self is "main",
so @a belongs to the "main" object. When you define methods in context
of the "main" object those methods are actually created as instance
methods on Object, which makes them available everywhere (since every
object in Ruby is_a? Object). So the @a at (b) refers to the @a of
whoever calls bar. At (c), "main" is calling bar, so its value of @a
(set at (a)) is used.
Let's try calling bar from the context of an object that doesn't have @a set:
@a = "foo" # belongs to "main"
def bar
puts(@a || "@a is empty!")
end
bar # => prints "foo"
module A
# "self" here is the module itself
bar # => prints "@a is empty!"
end
So, the moral? The above construct where you have @a defined at the
top level and then (tried) to use in a top level method only works by
accident. While it works in the common case where used, it's not
correct and can lead to errors when the top level method is called in
a context *other* than the top level. If you *really* need that sort
of behavior, use globals ($a). That's what they're for. But, of
course, if you find yourself needing globals you probably want to
rethink your approach. :)
Hope that made sense...
Jacob Fugal