我创建了一个项目,其中我有很多类,每个类都有一个类似的结构:
module Project
class ExampleClass
attr_accessor :title, :body, :elements_1, :elements_2
def initialize(attributes = {})
self.title = attributes[:title]
self.body = attributes[:body]
self.elements1 = attributes[:elements1] || []
self.elements2 = attributes[:elements2] || []
end
def ==(other)
title == other.title && body == other.body && elements1 == other.elements1 && elements2 == other.elements2
end
end
end
只有类之间的差异是elements1
和elements2
数组的名称和名称。
我的导师给了我代码来干我的项目:
module Project
class Node
extend ActiveModel::Naming
include ActiveModel::Model
attr_accessor :body, :title
cattr_accessor :element_names
self.element_names = []
def element
element_names.reduce([]) do |name, memo|
memo + send(name)
end
end
def ==(other)
body == other.body && title == other.title && element_names.all? { |name| element_by_name(name) == other.element_by_name(name) }
end
def element_by_name(name)
instance_variable_get("@#{name}") || instance_variable_set("@#{name}", [])
end
module ClassMethods
def element(name)
elements_names << name
attr_writer name
define_method(name) do
element_by_name(name)
end
end
end
extend ClassMethods
end
end
它高于我的水平,我试图让它发挥作用 - 每个班级都应该在Node
之后继承。我必须以某种方式传递属性 - elements1
和elements2
。我正在尝试
class ExampleClass < Node
cattr_accessor :element_names
self.element_names = [:elements1, elements2]
end
在我的ExampleClass
中传递数组的名称。
我也试过了initialize
,但我无法让它发挥作用。我会感激任何帮助。
答案 0 :(得分:1)
element
类方法用于定义新元素。
你想要像
这样的东西class ExampleClass < Node
element :elements1
element :elements2
end
虽然您的导师给您的代码存在严重问题:元素名称存储在类变量中,这意味着它们将在Node
的所有子类之间共享。你想要的是类实例变量。
替换此
cattr_accessor :element_names
self.element_names = []
用这个
def self.element_names
@element_names ||= []
end
这样每个子类都存储自己的元素名称数组(然后作为奖励你不再需要ActiveModel
任何一个。)