在 class 之外获取 attr_reader、编写器或访问器
Get attr_reader, writer, or accessor oustide of the class
我目前正在使用 ruby 进行一些元编程,并且我正在尝试隔离 class 的方法(class 在另一个文件中,我通过一个要求)。我可以得到所有的方法,多亏了 klass.public_instance_methods(false),但我同时给定的数组也有 class 的所有属性。我怎么能隔离他们?在关于 SO 的其他相关问题中,他们建议使用 klass.instance_variables 但是当我这样做时,它只是 returns 一个空数组。
我似乎无法理解那个问题。我不明白为什么没有专门针对该问题的方法...
例如:
我在文件中有这个 class :
class T
attr_reader:a
def initialize(a)
@a = a
end
def meth
#code here
end
end
并且,在另一个文件中,我有
require_relative 'T.rb'
class meta
def initialize
methods = T.public_instance_methods(false) #=> here methods = [:a,:meth] but I would want only to have [:meth]
#rest of code
end
end
对于 class 定义如下:
class Klass
attr_accessor :variable
def initialize(variable)
@variable = variable
end
def method
end
end
您可以使用 public_instance_methods
和 instance_variables
方法找到 public non-attr 个实例方法。
public_instance_methods = Klass.public_instance_methods(false)
# [:method, :variable, :variable=]
instance_variables = Klass.new(nil).instance_variables
# [:@variable]
getters_and_setters = instance_variables
.map(&:to_s)
.map{|v| v[1..-1] }
.flat_map {|v| [v, v + '=']}
.map(&:to_sym)
# [:variable, :variable=]
without_attr = public_instance_methods - getters_and_setters
# [:method]
这是不可能的。 Ruby 的 "attributes" 是完全正常的方法。无法将它们与其他方法区分开来。比如这两个类完全没有区别:
class Foo
attr_reader :bar
end
class Foo
def bar
@bar
end
end
你可以尝试变聪明,根据实例变量过滤掉它们,但这很危险:
class Foo
# can filter this out using @bar
attr_writer :bar
def initialize
@bar = []
end
end
class Foo
def initialize
@bar = []
end
# this looks the same as above, but isn't a normal attribute!
def bar= x
@bar = x.to_a
end
end
我目前正在使用 ruby 进行一些元编程,并且我正在尝试隔离 class 的方法(class 在另一个文件中,我通过一个要求)。我可以得到所有的方法,多亏了 klass.public_instance_methods(false),但我同时给定的数组也有 class 的所有属性。我怎么能隔离他们?在关于 SO 的其他相关问题中,他们建议使用 klass.instance_variables 但是当我这样做时,它只是 returns 一个空数组。
我似乎无法理解那个问题。我不明白为什么没有专门针对该问题的方法...
例如:
我在文件中有这个 class :
class T
attr_reader:a
def initialize(a)
@a = a
end
def meth
#code here
end
end
并且,在另一个文件中,我有
require_relative 'T.rb'
class meta
def initialize
methods = T.public_instance_methods(false) #=> here methods = [:a,:meth] but I would want only to have [:meth]
#rest of code
end
end
对于 class 定义如下:
class Klass
attr_accessor :variable
def initialize(variable)
@variable = variable
end
def method
end
end
您可以使用 public_instance_methods
和 instance_variables
方法找到 public non-attr 个实例方法。
public_instance_methods = Klass.public_instance_methods(false)
# [:method, :variable, :variable=]
instance_variables = Klass.new(nil).instance_variables
# [:@variable]
getters_and_setters = instance_variables
.map(&:to_s)
.map{|v| v[1..-1] }
.flat_map {|v| [v, v + '=']}
.map(&:to_sym)
# [:variable, :variable=]
without_attr = public_instance_methods - getters_and_setters
# [:method]
这是不可能的。 Ruby 的 "attributes" 是完全正常的方法。无法将它们与其他方法区分开来。比如这两个类完全没有区别:
class Foo
attr_reader :bar
end
class Foo
def bar
@bar
end
end
你可以尝试变聪明,根据实例变量过滤掉它们,但这很危险:
class Foo
# can filter this out using @bar
attr_writer :bar
def initialize
@bar = []
end
end
class Foo
def initialize
@bar = []
end
# this looks the same as above, but isn't a normal attribute!
def bar= x
@bar = x.to_a
end
end