I was under the impression that class definitions in Ruby can be reopened:
class C
def x
puts 'x'
end
end
class C
def y
puts 'y'
end
end
This works as expected and y
is added to the original class definition.
I'm confused as to why the following code doesn't work as expected:
class D
x = 12
end
class D
puts x
end
This will result in a NameError
exception. Why is there a new local scope started when a class is reopened? This seems a little bit counterintuitive. Is there any way to continue the previous local scope when a class is extended?
A scope is a region of the program and broadly speaking there are three places, where variables can be declared: Inside a function or a block which is called local variables, In the definition of function parameters which is called formal parameters. Outside of all functions which is called global variables.
A class variable is a variable that is shared amongst all instances of a class. This means that only one variable value exists for all objects instantiated from this class. This means that if one object instance changes the value of the variable, that new value will essentially change for all other object instances.
Example 1: Local Scope Variable In the above program, variable a is a global variable and variable b is a local variable. The variable b can be accessed only inside the function greet . Hence, when we try to access variable b outside of the function, an error occurs.
Local Variables Variables defined within a function or block are said to be local to those functions. Anything between '{' and '}' is said to inside a block. Local variables do not exist outside the block in which they are declared, i.e. they can not be accessed or used outside that block.
Local variables are not associated with an object, they are associated with a scope.
Local variables are lexically scoped. What you are trying to do is no more valid than:
def foo
x = :hack if false # Ensure that x is a local variable
p x if $set # Won't be called the first time through
$set = x = 42 # Set the local variable and a global flag
p :done
end
foo #=> :done
foo #=> nil (x does not have the value from before)
#=> done
In the above it's the same method, on the same object, that's being executed both times. The self
is unchanged. However, the local variables are cleared out between invocations.
Re-opening the class is like invoking a method again: you are in the same self
scope, but you are starting a new local context. When you close the class D
block with end
, your local variables are discarded (unless they were closed over).
In ruby, local variables accessible only in scope that they are defined. However, the class
keywords cause an entirely new scope.
class D
# One scope
x = 12
end
class D
# Another scope
puts x
end
So, you can't get access to local variable that defined in first class
section, because when you leave first scope, local variable inside it is destroyed and memory is freed by garbage collection.
This is also true for the def
, for example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With