是否可以像RoR中的数组一样访问attr_reader变量?

时间:2016-08-29 17:17:03

标签: ruby-on-rails ruby attributes

我有一个看起来像这样的课程:

class AwsAssets
    attr_reader :AWS_INSTANCE, :AWS_INSTANCE_RESERVATION, :AWS_AVAILABILITY_ZONE

    @@AWS_INSTANCE = 1
    @@AWS_INSTANCE_RESERVATION = 2
    @@AWS_AVAILABILITY_ZONE = 3
end

我试图在另一个文件中访问这些变量ID。我想按照以下方式做点什么:

def index
    types = AwsAssets.attr_reader
    @filter = "model_type_id NOT IN (#{types.join(', ')})"
end

这显然不是正确的语法,我只是想知道我是否可以以某种方式访问​​所有attr_reader变量 - 我意识到我可以将所有属性放入一个数组中,但有100个我必须复制的变量,我宁愿不做。

2 个答案:

答案 0 :(得分:1)

有些元编程可能对你有帮助。

class AwsAssets
    # define your attributes here in a constant which is accessible from other classes
    ATTRIBUTES = [:AWS_INSTANCE, :AWS_INSTANCE_RESERVATION, :AWS_AVAILABILITY_ZONE]

    # use the definition above to call `attr_reader` for each attribute in the array
    ATTRIBUTES.each { |attribute| attr_reader(attribute) }
    # OR a shortcut: attr_reader(*ATTRIBUTES)
end

def index
    # You can now access that array of attributes in other areas like so
    types = AwsAssets.ATTRIBUTES
    @filter = "model_type_id NOT IN (#{types.join(', ')})"
end

这是一个很好的资源,可以获得有关Ruby中元编程的更多示例和信息:Introduction to Ruby Meta-Programming Techniques

答案 1 :(得分:1)

在您的代码中,您混合了几个可以在类上定义的不同属性,因此我不确定您要使用哪个属性。

您可以使用类实例变量

class AwsAssets
  @AWS_INSTANCE = 1
  @AWS_INSTANCE_RESERVATION = 2
  @AWS_AVAILABILITY_ZONE = 3
end

AwsAssets.instance_variables
# => [:@AWS_INSTANCE, :@AWS_INSTANCE_RESERVATION, :@AWS_AVAILABILITY_ZONE]
AwsAssets.instance_variable_get "@AWS_INSTANCE"
# => 1

或者您可以使用类变量

class AwsAssets
  @@AWS_INSTANCE = 1
  @@AWS_INSTANCE_RESERVATION = 2
  @@AWS_AVAILABILITY_ZONE = 3
end

AwsAssets.class_variables
# [:@@AWS_INSTANCE, :@@AWS_INSTANCE_RESERVATION, :@@AWS_AVAILABILITY_ZONE]
AwsAssets.class_variable_get "@@AWS_INSTANCE""
# => 1

使用@@创建类变量时,此类和所有子类的值都相同。如果将类实例变量与@一起使用,则可以为父类和子类使用不同的值。