ruby 获取类中声明的所有示例变量

rfbsl7qr  于 2023-06-22  发布在  Ruby
关注(0)|答案(6)|浏览(120)

请帮助我获取类中声明的所有示例变量,就像instance_methods显示类中所有可用的方法一样。

class A
  attr_accessor :ab, :ac
end

puts A.instance_methods  #gives ab and ac

puts A.something         #gives me @ab @ac...
o8x7eapl

o8x7eapl1#

可以使用instance_variables

A.instance_variables

但这可能不是您想要的,因为它获取的是 classA中的示例变量,而不是该类的示例。所以你可能想要:

a = A.new
a.instance_variables

但是请注意,仅仅调用attr_accessor并没有定义任何示例变量(它只是定义了方法),所以在显式设置它们之前,示例中不会有任何示例变量。

a = A.new
a.instance_variables #=> []
a.ab = 'foo'
a.instance_variables #=> [:@ab]
bvpmtnay

bvpmtnay2#

如果你想获取所有示例变量的值,你可以尝试这样做:

class A
  attr_accessor :foo, :bar

  def context
    self.instance_variables.map do |attribute|
      { attribute => self.instance_variable_get(attribute) }
    end
  end
end

a = A.new
a.foo = "foo"
a.bar = 42
a.context #=> [{ :@foo => "foo" }, { :@bar => 42 }]
unguejic

unguejic3#

这并不是万无一失的-可以在类上定义与模式匹配的其他方法-但我发现一种适合我需要的方法是

A.instance_methods.grep(/[a-z_]+=/).map{ |m| m.to_s.gsub(/^(.+)=$/, '@\1') }
5jvtdoz2

5jvtdoz24#

如果你想得到所有示例变量的散列,以属性的方式,按照Aschen的回答你可以做到

class A
  attr_accessor :foo, :bar

    def attributes
    self.instance_variables.map do |attribute|
      key = attribute.to_s.gsub('@','')
      [key, self.instance_variable_get(attribute)]
    end.to_h
  end
end
a = A.new
a.foo = "foo"
a.bar = 42
a.context #=> {'foo' => 'foo', 'bar' => 42}
wqsoz72f

wqsoz72f5#

基于@Obromios的答案,我将.to_h.to_s添加到一个类中,以允许愉快,灵活地转储适合显示给最终用户的属性。
这个特殊的类(不是ActiveRecord模型)将在不同的情况下设置各种属性。打印myvar.to_s时,只有那些有值的属性才会出现,这是我的愿望。

class LocalError
  attr_accessor :product_code, :event_description, :error_code, :error_column, :error_row 

  def to_h
    instance_variables.map do |attribute|
      key = attribute.to_s.gsub('@', '')
      [key, self.instance_variable_get(attribute)]
    end.to_h
  end

  def to_s
    to_h.to_s
  end
end

这允许我把这个简单的代码放在邮件模板中:

Data error:   <%= @data_error %>

它产生(例如):

Data error:   {"event_description"=>"invalid date", "error_row"=>13}

这很好,因为将来LocalError属性更改时,邮件程序不必更新。

myss37ts

myss37ts6#

如果你运行byebug,你可以运行instance_variables来获取运行时生成的列表。
这可能是一个新功能。运行ruby 3.2.2

相关问题