ruby - 如何动态地为类创建 attr_reader
问题描述
如何动态地在对象上创建属性并将对象分配给它的值?我有以下代码:
class Component
def initialize
end
end
class BaseClass
def initialize
end
# define class methods
def self.create_component(**args)
# create attr_accessor with name "ball"
# set ball = Component.new
end
end
class ChildClass < BaseClass
create_component :name => "ball"
create_component :name => "baseball"
def initialize
end
end
我的目标是,当 ChildClass 调用“create_component”方法时,这应该使用 :name 参数中提供的名称创建一个属性,并将一个“组件”对象实例化到该属性。
object = ChildClass.new
object.ball #=> to return object reference (Component class 1)
object.baseball #=> to return object reference (Component class 2)
解决方案
您可以像这样定义 BaseClass :
class Component; end
class BaseClass
@@components = []
def initialize
@@components.each do |attr|
instance_variable_set("@#{attr}", Component.new)
end
end
def self.create_component(name:)
attr_reader name.to_sym
@@components << name
end
end
class ChildClass < BaseClass
create_component :name => "ball"
create_component :name => "baseball"
end
object = ChildClass.new
object.ball
# => #<Component:0x00007fa62fbdf3f8>
object.baseball
# => #<Component:0x00007fa62fbdf3a8>
基本上你做三件事:
@@components
创建一个存储自定义attr_reader
名称列表的类级实例变量- 在内部
create_component
,调用attr_reader
创建方法并将其添加到@@components
列表中 - 在内部
initialize
,为每个设置初始值(如果您愿意,也可以使用参数@@components
为这些自定义值)。initialize
推荐阅读
- amazon-web-services - 与电子邮件关联的 S3 存储桶
- angular - Could not set the default value of selection at Angular 6
- python - 未填充外键的表
- javascript - Node.js,无法在 MacOS 上安装 enmap 级别
- css - SCSS 问题中的字体
- react-native - 请如何在本地创建 json 对象以循环到此视图
- c# - C# - Postgres - 随着时间的推移内存泄漏问题
- c++ - 如何合并字符数组中的两个数组以通过网络发送
- python - TensorFlow LSTM:为什么测试准确率变低,但不能训练?
- php - 如何打破 PHP 多维数组?