2

概述:

main.rb
items/
    one.rb
    two.rb
    three.rb

每个文件都items/应该有一个人类可读的描述(序列化已结束),就像这样(但也许 DSL 会更好?):

class One < BaseItem
    name "Item one"
    def meth
        "something"
    end

main.rb应该能够实例化items/目录中的所有对象。这怎么可能实现?不熟悉 Ruby,我看到对象模型允许一些非常酷的东西(那些类挂钩等),但我很难找到解决这个问题的方法。

任何输入方式表示赞赏。

编辑:

射击,我可能错过了它的要点 - 我没有提到items/目录中的东西是动态的 - 将项目视为插件,我想main.rb在运行时自动检测该目录中的所有内容(可能在期间强制重新加载执行)。main.rb对那里的对象没有先验知识,它只知道可以从它们那里得到什么方法。

我已经研究过构建 DSL,考虑定义 (in main.rb) 一个spawn带块的函数。中的示例文件items/如下所示:

spawn do
    name "Item name"
    def foo
        "!"
    end
end

并且内部spawn将创建一个基本类型的新对象并将块传递给instance_eval. 这意味着我需要有一个方法name来设置值,但顺便说一句,我还希望在 下可以访问该值name,所以我不得不绕过它重命名 attr。

我也尝试过继承路线:让每个项目文件都包含一个从 a 继承的类BaseItem,并通过inherited...挂钩它,但这没有用(挂钩从未触发,我现在丢失了代码)。

编辑2:

你可以看看自制软件对它的公式做了什么,这非常接近我想要的——我只是没有红宝石的能力来逆向工程它如何处理一个公式。

4

3 回答 3

2

这一切都归结为需要这些文件,并确保您在其中实现了您想要的功能。

如果您想要更具体的回答,您需要提出更具体的问题。

于 2013-04-30T11:11:45.560 回答
0

我不是对象持久性方面的专家,但对您的具体问题的回答是,您有 2 个不错的选择:一个是 YAML,另一个是 Ruby 本身:由您或其他人编写的 DSL,特定于您的业务逻辑。

但我认为更一般的答案需要更系统地审查 Ruby 中的对象持久性。例如,ActiveRecord::Base 后代保留为数据库表。还有其他方法,我发现例如。这个http://stone.rubyforge.org/通过谷歌搜索。这也是我的问题,我在工作中遇到了和你一样的问题。

于 2013-04-30T11:20:45.210 回答
0

您所要求的外观和气味很像普通的 Ruby 脚本。

class One < BaseItem
    name "Item one"
    def meth
        "something"
    end

我们会用另一个end语句来结束类定义。name "Item one"可能会initialize通过设置实例变量在方法内部完成:

attr_reader :name
def initialize(name)
  @name = name
end

通常我们不会将文件夹称为“items”,而是将其称为“lib”,否则您所谈论的内容是非常正常和预期的。

实例化文件夹中的所有项目很容易通过迭代文件夹的内容、需要文件并调用该new项目的方法来完成。您可以通过将文件名映射到类名来确定名称,或者通过在文件末尾初始化一个实例来确定名称:

one = One.new("item one")

您可以跟踪加载到数组或哈希中的项目,或者只是硬连线它们。这取决于您,因为这是您的代码。

听起来您还没有尝试过编写任何 Ruby 脚本,否则您早就发现了这一点。普通的 Ruby 编程书籍/文档会涵盖这一点。事实上,这个问题类似于过早的优化,使用该语言会给你答案。

于 2013-04-30T11:25:09.950 回答