class MainController < ApplicationController
@my_var = 123
def index
var1 = @my_var
end
def index2
var2 = @my_var
end
end
Tại sao không phải là var1
không var2
bằng 123
?Rails và các biến lớp
class MainController < ApplicationController
@my_var = 123
def index
var1 = @my_var
end
def index2
var2 = @my_var
end
end
Tại sao không phải là var1
không var2
bằng 123
?Rails và các biến lớp
Biến với @
là các biến mẫu trong ruby. Nếu bạn đang tìm kiếm các biến lớp, chúng được bắt đầu bằng @@
, vì vậy bạn nên sử dụng @@my_var = 123
để thay thế.
Và lý do bạn không thể sử dụng biến mẫu theo cách đó, là vì bạn xác định biến mẫu bên ngoài phương thức, chúng không sống trong cùng phạm vi với phương pháp của bạn, nhưng chỉ sống trong khi lớp của bạn được diễn giải.
var1
trong ví dụ của bạn là biến cục bộ, biến này sẽ chỉ hiển thị trong phương thức index
.
Ví dụ:
class Foo
@@class_variable = "I'm a class variable"
def initialize
@instance_variable = "I'm an instance variable in a Foo class"
local_variable = "I won't be visible outside this method"
end
def instance_method_returning_an_instance_variable
@instance_variable
end
def instance_method_returning_a_class_variable
@@class_variable
end
def self.class_method_returning_an_instance_variable
@instance_variable
end
def self.class_method_returning_a_class_variable
@@class_variable
end
end
Foo.new
=> #<Foo:0x007fc365f1d8c8 @instance_variable="I'm an instance variable in a Foo class">
Foo.new.instance_method_returning_an_instance_variable
=> "I'm an instance variable in a Foo class"
Foo.new.instance_method_returning_a_class_variable
=> "I'm a class variable"
Foo.class_method_returning_an_instance_variable
=> nil
Foo.class_method_returning_a_class_variable
=> "I'm a class variable"
Bởi vì đoạn mã thực thi trong bối cảnh khác nhau. Bạn có thể xem tại đây:
class MainController
puts self
def print_self
puts self
end
end
#=> MainController
MainController.new.print_self #=> <MainController:0x00000001761140>
Như bạn có thể thấy trong bản in đầu tiên tự ngã là MainController
, in thứ hai tự là đối tượng mà có nguồn gốc từ MainController
lớp.
Trong gán cho @my_vay biến này thuộc về MainController, và trong trường hợp thứ hai, @my_var thuộc về đối tượng (không phải là một lớp) và các biến khác nhau.
@my_var
, trong mã mẫu của bạn, là một biến mẫu trên lớp MainController
. Tức là, nó là một biến cá thể cấp lớp, và không phải là một biến cá thể mức cá thể. Nó tồn tại trong một phạm vi hoàn toàn khác với biến cá thể kết hợp với một cá thể của lớp.
Trong cơ thể của dụ phương pháp của bạn, index
và index2
, bạn đang cố gắng để dereference một biến Ví dụ về một đối tượng mà là một thể hiện của lớp MainController
, nhưng bạn chưa xác định rằng biến dụ bất cứ nơi nào, vì vậy bạn sẽ có được trở lại nil
.
Nếu bạn muốn sử dụng @my_var
như là một biến thể hiện lớp cấp, bạn có thể nhận được giá trị của nó từ bên trong một thể hiện của lớp như thế này:
var1 = self.class.instance_variable_get(:@my_var)
biến lớp được biểu thị bằng tiền tố @@
, và việc sử dụng chúng không được khuyến khích hoàn toàn. Một vài phút với Google sẽ cho bạn biết lý do.
Vì vậy, sự khác nhau giữa @var và var là gì? – Alexandre
'@ var' là một biến cá thể, sẽ được hiển thị trong tất cả các phương thức trong một cá thể của lớp. 'var' là một biến cục bộ, biến này chỉ hiển thị trong phạm vi được xác định. – Frost
Ok, sự khác nhau giữa @var và @@ var là gì? – Alexandre