Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在Ruby 1.9中,访问类变量的正确方法是什么?_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails 在Ruby 1.9中,访问类变量的正确方法是什么?

Ruby on rails 在Ruby 1.9中,访问类变量的正确方法是什么?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我试图设置一些类变量来存储Rails应用程序中的路径(但我认为这更像是一个ruby问题) 基本上我的班级是这样的 class Image < ActiveRecord::Base @@path_to_folder = "app/assets" @@images_folder = "upimages" @@path_to_images = File.join(@@path_to_folder, @@images_folder) end 我想,我尝试了所有可能的方法(包

我试图设置一些类变量来存储Rails应用程序中的路径(但我认为这更像是一个ruby问题)

基本上我的班级是这样的

class Image < ActiveRecord::Base

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

end

我想,我尝试了所有可能的方法(包括前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

在某些情况下,类变量比替代变量更合理,但这些情况通常非常罕见。

Rails为该功能提供了类级属性访问器

试一试

但是人们总是建议避免类变量,因为它在继承中的行为

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

虽然我一般不推荐使用它,但您可以通过向
class\u eval
传递字符串来访问类变量,如下所示:

Image.class_eval('@@path_to_folder')
至少在Ruby的更高版本中是这样


但是,请注意,类变量与子类层次结构中最上层的类相关联。对于像这样的ActiveRecord子类,这意味着这些类变量确实存在于
ActiveRecord::Base

的命名空间中,您可以通过将其包装在类方法中来实现,如下所示:

def self.path_to_images
  @@path_to_images
end
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

但是我应该提到,如果您不能或不想扩展类的使用,您应该尽量避免在rails中使用类变量:

Image.class_variable_get(:@@path_to_images)

我会这样修改它:

def self.path_to_images
  @@path_to_images
end
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
现在这将起作用:

Image.path_to_folder

最好的方法是使用方法设置和获取值。下面是一个示例代码

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

为什么不使用类常量?您需要访问器(
cattr\u访问器
)从外部访问类变量。两个答案都很好谢谢,但我只能检查其中一个:(
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
def self.path_to_folder
  @@path_to_folder
end
Image.path_to_folder
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