I am new to Ruby language. I understand that
@@count: Class variables
@name: Instance variables
my_string: Local variables
I keep the above in mind. However, I found one Ruby code like this:
class HBaseController < ApplicationController
...
def result
conn = OkHbase::Connection.new(host: 'localhost', port: 9090, auto_connect: true)
...
end
end
'conn' confuses me a lot.
Is 'conn' a instance variable, or local variable? And what is the scope of 'conn'?
I try to explain it with a little example:
class MyClass
def meth
conn = 1
end
def result
conn
end
end
x = MyClass.new
p x.result #-> test.rb:6:in `result': undefined local variable or method `conn'
conn
is unknown. Let's try to call meth
before:
class MyClass
def meth
conn = 1
end
def result
conn
end
end
x = MyClass.new
x.meth # try to create conn
p x.result #-> test.rb:6:in `result': undefined local variable or method `conn'
Same result. So conn
is no instance variable. You define a local variable in meth
but it is unknown outside.
Let's try the same with instance variables:
class MyClass
def meth
@conn = 1
end
def result
@conn
end
end
x = MyClass.new
p x.result #-> nil (no value assigned (*), but is is existing)
x.meth # initialze @conn with a value
p x.result #-> 1
With the usage of accessor-methods you define implicit an instance variable:
class MyClass
attr_reader :conn
def meth
conn = 1
end
def result
conn
end
end
x = MyClass.new
p x.result #-> nil (no value assigned (*), but is is existing)
x.meth # define conn with a value
p x.result #-> nil - the instance variable is not changed, a locale variable was used
In method result
the conn
is the reader method conn
. In the method meth
it is a locale variable (this can be confusing, because now you have a variable with the same name as a variable.
If you want to change the conn
-value in the meth
-method you must define a setter and use self.conn
:
class MyClass
attr_reader :conn
attr_writer :conn
def meth
self.conn = 1
end
def result
conn
end
end
x = MyClass.new
p x.result #-> nil (not defined yet, but is is existing)
x.meth # define conn with a value
p x.result #-> 1
You can replace attr_reader
and attr_writer
with attr_accessor
.
(*) Remark: I wrote no value assigned - this is not really correct, nil
is also a value.
In this case, conn
is local variable.
EDIT:
conn would be a instance variable if you had it written like
@conn = OkHbase::Connection.new(host: 'localhost', port: 9090, auto_connect: true)
conn
is a local variable (local variables start with a lower case letter or an underscore)
It contains an instance of OkHbase::Connection
Presumably the code that was omitted ...
uses that object. Because it's a local variable, once the result
method is ended, the local variable will no longer be accessible and the object will be cleared from memory.
(Of course, it's possible the omitted code assigned the object in conn
to an instance variable or passed it into some other method that has stored it elsewhere)
conn
is local to the method result
Blocks create a new scope, as do methods and class declarations. Interestingly, if
statements do not create a new local scope, so variables you declare inside of an if
statement is available outside.
$ irb
1.9.3-p484 :001 > if true
1.9.3-p484 :002?> foo = 1
1.9.3-p484 :003?> end
=> 1
1.9.3-p484 :004 > foo
=> 1
1.9.3-p484 :005 > 1.times do
1.9.3-p484 :006 > bar = 1
1.9.3-p484 :007?> end
=> 1
1.9.3-p484 :008 > bar
NameError: undefined local variable or method `bar' for main:Object
from (irb):8
from irb:12:in `<main>'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.