Нормальные переменные против переменной экземпляра в Ruby, в чем разница?
рассмотрим следующий пример ruby class
class User
def hello
puts "hello"
end
end
Теперь, для инициализации. есть два пути
нормальная переменная
1.9.3p125 > tr = User.new
=> #<User:0x98778c4>
1.9.3p125 > tr.hello
Hello world
=> nil`
переменные экземпляра:
1.9.3p125 > @tr = User.new
=> #<User:0x9890f2c>
1.9.3p125 > @tr.hello
Hello world
=> nil
Итак, в обоих случаях работает одинаково. Итак, в чем разница между нормальной переменной и переменной экземпляра?
3 ответов
обычная переменная имеет область действия только в текущем контексте; переменная экземпляра имеет область действия во всем экземпляре класса. В вашем случае они путаются, потому что контекст main
, который действует как экземпляр Object
.
рассмотрим следующее, что может сделать вещи яснее
class User
def set_name
@name = "Bob"
surname = "Cratchett"
end
def hi
puts "Hello, " + @name
end
def hello
puts "Hello, Mr " + surname
end
end
irb(main):022:0> u = User.new
=> #<User:0x29cbfb0>
irb(main):023:0> u.set_name
irb(main):024:0> u.hi
Hello, Bob
=> nil
irb(main):025:0> u.hello
NameError: undefined local variable or method `surname' for #<User:0x29cbfb0 @name="Bob">
нормальная переменная называется локальная переменная и является локальным для конструкции кода, в которой он был определен (если вы определяете его в методе, он не может быть доступен вне этого метода).
An переменная является локальным для определенного экземпляра объекта. Если один объект изменяет значение переменной экземпляра, изменение происходит только для этого объекта.
также переменные класса local для всех экземпляров класс:
@@class_variable = 'a class variable'
и глобальные переменные доступно из любой точки программы:
$global_variable = 'a global variable'
локальная переменная может использоваться только внутри метода, в котором она определена (или, когда переменная определена на верхнем уровне, только вне любого метода). Переменная экземпляра может использоваться из любого метода, вызываемого в том же экземпляре.
вот пример, где вы можете увидеть разницу:
@tr = User.new
def foo
@tr.hello
end
foo
# Hello World
tr = User.new
def bar
tr.hello
end
bar
# Exception because tr is not accessible from within bar