2012-09-25 83 views
21

我想設置一些類變量存儲在Rails應用程序路徑(但我認爲這更多的是紅寶石的問題)在Ruby 1.9中訪問類變量的正確方法是什麼?

基本上我的階級是這樣

class Image < ActiveRecord::Base 

    @@path_to_folder = "app/assets" 
    @@images_folder = "upimages" 
    @@path_to_images = File.join(@@path_to_folder, @@images_folder) 

end 

但是,當我嘗試通過做Image.path_to_images訪問@@path_to_images從我的控制,我得到一個NoMethodError

當我試着使用Image.class_eval(@@path_to_images),我得到uninitialized class variable @@path_to_images in ImagesController

我已搜索周圍,所有我見過的說,這些會的工作,所以我對這個

更重要的是很迷茫,我試圖定義簡單類與紅寶石控制檯,像這樣

class Bidule 
    @@foo = "foo" 
    Bar = "bar" 
end 

所以我試着,盡我所能(訪問前兩個版本)來訪問它們,但沒有辦法總是得到異常提出

+2

爲什麼不是類常量?你需要訪問器('cattr_accessor')來訪問外部的類變量。 http://apidock.com/rails/Class/cattr_accessor – tokland

回答

24

Rails提供一流水平的屬性訪問器這個功能

嘗試

class Image < ActiveRecord::Base 
    cattr_accessor :path_to_folder 
    @@path_to_folder = "app/assets" 
end 

然後訪問path_to_folder類變量,只是使用

Image.path_to_folder 

但人們總是建議,以避免因類變量它的行爲繼承。所以你可以使用常量,如

class Image < ActiveRecord::Base 
    PATH_TO_FOLDER = "app/assets" 
end 

然後你就可以訪問諸如

Image::PATH_TO_FOLDER 
2

在Ruby應用程序中很少使用類變量,因爲它們有很多限制,傾向於違背適當的面向對象設計的粒度。

在幾乎所有情況下,類變量都可以用適當的常量,類方法或兩者替換。

你的例子可能是更好的描述爲:

class Image < ActiveRecord::Base 
    PATH_TO_FOLDER = "app/assets" 
    IMAGES_FOLDER = "upimages" 
    PATH_TO_IMAGES = File.join(PATH_TO_FOLDER, IMAGES_FOLDER) 
end 

類變量是私有的問題的上課不涓滴子類和難以從外部環境訪問。使用常量讓喜歡使用的東西:

image_path = Image::PATH_TO_FOLDER 

有一些情況下使用類變量是比選擇更合理的,但這些通常是非常罕見的。

+0

這兩個答案真的很好,謝謝,我只能檢查一個:( –

9

恆雖然我不是一般的建議是,你可以通過一個字符串訪問類變量class_eval爲:

Image.class_eval('@@path_to_folder') 

至少在更高版本的Ruby中。

但是請注意,類變量與子類層次結構中最上面的類相關聯。對於像這樣的ActiveRecord子類,這意味着這些類變量確實存在於ActiveRecord::Base的名稱空間中。

+1

醜陋,但做的工作,謝謝! – akostadinov

1

你可以通過它包裹在一個類的方法,就像這樣:

def self.path_to_images 
    @@path_to_images 
end 

,但我要指出,你應該儘量避免在軌

3

使用類變量如果不能或者不希望擴展類使用:

Image.class_variable_get(:@@path_to_images) 
1

我會修改這樣的:

class Image < ActiveRecord::Base 

    @@path_to_folder = "app/assets" 
    @@images_folder = "upimages" 
    @@path_to_images = File.join(@@path_to_folder, @@images_folder) 

    def initialize 
    end 
    ... 
    def self.path_to_folder 
    @@path_to_folder 
    end 
end 

你在這裏所做的是將類變量變成一個方法,所以你現在可以訪問使用.method名稱調用。既然這是一個類變量,你只能在類本身而不是在類的實例上調用它。 由於您使用不存在的方法調用類變量,因此您正在收到'NoMethodError'。上面的代碼定義了,你說行這種方法:

def self.path_to_folder 
    @@path_to_folder 
end 

現在這將工作:

Image.path_to_folder 
2

最好的辦法是設置和使用方法獲得的價值。下面是一個示例代碼

class Planet 
    @@planets_count = 0 

    def initialize(name) 
    @name = name 
    @@planets_count += 1 
    end 

    def self.planets_count 
    @@planets_count 
    end 

    def self.add_planet 
    @@planets_count += 1 
    end 

    def add_planet_from_obj 
    @@planets_count += 1 
    end 
end 


Planet.new("uranus") 
Plant.add_planet 
obj = Planet.new("earth") 
obj.add_planet_from_obj 
相關問題