如何在Ruby中在类和类实例之间共享数据



为了在类和类实例之间共享数据,ActiveSupport拥有出色的方法class_attribute。例如

require 'active_support/core_ext/class/attribute.rb'
# Step 1: declare a class record and implement class_attribute :fields.
# We can use it to declare attr_accessor
class Record
class_attribute :fields
self.fields = [:id]
def self.attribute(new_field_name)
self.fields = fields | [new_field_name]
instance_eval do
attr_accessor new_field_name
end
end
end
# Step 2: Declare class Topic with two attributes
class Topic < Record
attribute :title
attribute :body
end
# Step 3: Declare another class user with other two attributes
# And one more class with addition attribute
class User < Record
attribute :first_name
attribute :last_name
end

# Step 4: Let's check.
# Each class has it own attributes and data is shared between class and instances
puts Topic.fields
# [:id, :title, :body]
puts Topic.new.fields
# [:id, :title, :body]
puts User.fields
# [:id, :first_name, :last_name]
puts User.new.fields
# [:id, :first_name, :last_name]

我写了一个小ruby脚本,不想对ActiveSupport有额外的依赖。此外,我不能使用类变量(带有"@@"的变量(,因为更改子类的值会影响父类。

关于选项-我可以将class_attribute源代码复制并粘贴到我的Ruby脚本中,但我很想在纯Ruby中找到一个解决方案🤔

关于如何在纯Ruby上轻松实现它,没有人能帮助我或给我建议吗?

也许为类实例变量定义一个attr_accessor,然后将所需的实例方法转发给类上的那些方法?

require 'forwardable'
class Foo
extend Forwardable
class << self
attr_accessor :fields
end
def_delegator self, :fields
def_delegator self, :fields=
end
foo = Foo.new
p Foo.fields #=> nil
p foo.fields #=> nil
Foo.fields = { set_on: 'Class' }
p foo.fields #=> {:set_on=>"Class"}
foo.fields = { set_on: 'instance' }
p Foo.fields #=> {:set_on=>"instance"}

最新更新