2012-07-17 31 views
5
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

Trả lời

22

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" 
+0

Vì vậy, sự khác nhau giữa @var và var là gì? – Alexandre

+2

'@ 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

+0

Ok, sự khác nhau giữa @var và @@ var là gì? – Alexandre

0

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.

2

@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, indexindex2, 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.

Các vấn đề liên quan