列出用attr_accessor
定义的所有方法的最短,单行方法是什么?我想这样做,如果我有一个类MyBaseClass
,任何扩展它的东西,我可以在子类中定义attr_accessor
。像这样:
class MyBaseClass < Hash
def attributes
# ??
end
end
class SubClass < MyBaseClass
attr_accessor :id, :title, :body
end
puts SubClass.new.attributes.inspect #=> [id, title, body]
如何仅显示attr_reader
和attr_writer
定义?
答案 0 :(得分:41)
将属性提取到数组中,将它们分配给constant,然后将splat分配到attr_accessor
。
class SubClass < MyBaseClass
ATTRS = [:id, :title, :body]
attr_accessor(*ATTRS)
end
现在您可以通过常量访问它们:
puts SubClass.ATTRS #=> [:id, :title, :body]
答案 1 :(得分:39)
没有办法(单行或其他方式)列出attr_accessor定义的所有方法,只列出attr_accessor定义的方法,而不定义自己的attr_accessor。
这是一个覆盖MyBaseClass中的attr_accessor的解决方案,用于记住使用attr_accessor创建的方法:
class MyBaseClass
def self.attr_accessor(*vars)
@attributes ||= []
@attributes.concat vars
super(*vars)
end
def self.attributes
@attributes
end
def attributes
self.class.attributes
end
end
class SubClass < MyBaseClass
attr_accessor :id, :title, :body
end
SubClass.new.attributes.inspect #=> [:id, :title, :body]
答案 2 :(得分:6)
继承人使用mixin而不是继承:
module TrackAttributes
def attr_readers
self.class.instance_variable_get('@attr_readers')
end
def attr_writers
self.class.instance_variable_get('@attr_writers')
end
def attr_accessors
self.class.instance_variable_get('@attr_accessors')
end
def self.included(klass)
klass.send :define_singleton_method, :attr_reader, ->(*params) do
@attr_readers ||= []
@attr_readers.concat params
super(*params)
end
klass.send :define_singleton_method, :attr_writer, ->(*params) do
@attr_writers ||= []
@attr_writers.concat params
super(*params)
end
klass.send :define_singleton_method, :attr_accessor, ->(*params) do
@attr_accessors ||= []
@attr_accessors.concat params
super(*params)
end
end
end
class MyClass
include TrackAttributes
attr_accessor :id, :title, :body
end
MyClass.new.attr_accessors #=> [:id, :title, :body]
答案 3 :(得分:2)
跟进Christian的回复,但修改为使用ActiveSupport :: Concern ......
module TrackAttributes
extend ActiveSupport::Concern
included do
define_singleton_method(:attr_reader) do |*params|
@attr_readers ||= []
@attr_readers.concat params
super(*params)
end
define_singleton_method(:attr_writer) do |*params|
@attr_writers ||= []
@attr_writers.concat params
super(*params)
end
define_singleton_method(:attr_accessor) do |*params|
@attr_accessors ||= []
@attr_accessors.concat params
super(*params)
end
end
def attr_readers
self.class.instance_variable_get('@attr_readers')
end
def attr_writers
self.class.instance_variable_get('@attr_writers')
end
def attr_accessors
self.class.instance_variable_get('@attr_accessors')
end
end
答案 4 :(得分:2)
class MyBaseClass
attr_writer :an_attr_writer
attr_reader :an_attr_reader
def instance_m
end
def self.class_m
end
end
class SubClass < MyBaseClass
attr_accessor :id
def sub_instance_m
end
def self.class_sub_m
end
end
p SubClass.instance_methods - Object.methods
p MyBaseClass.instance_methods - Object.methods
a = SubClass.new
b = MyBaseClass.new
p a.methods - Object.methods
p b.methods - Object.methods
#=> [:id, :sub_instance_m, :id=, :an_attr_reader, :instance_m, :an_attr_writer=]
#=> [:an_attr_reader, :instance_m, :an_attr_writer=]
attr_accessor既是attr_writer又是attr_reader
attr_reader在方法名称
之后输出no =attr_writer在方法名称
之后输出=您始终可以使用正则表达式来过滤该输出。
答案 5 :(得分:0)
可以使用等号匹配逻辑对其进行过滤:
X (T r t) b