Ruby:从文件中实例化对象

时间:2013-04-30 11:05:12

标签: ruby

概述:

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/ dir中的内容是动态的 - 将项目视为插件,我希望main.rb来在运行时自动检测该目录中的所有内容(可能在执行期间强制重新加载)。 main.rb之前没有对象的先验知识,只知道从中得到什么方法。

我考虑过构建DSL,考虑定义(在main.rb中)一个spawn函数,它接受一个块。 items/中的示例文件类似于:

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

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

我还尝试了继承路由:让每个项目文件都包含一个继承自BaseItem种类的类,并通过inherited挂钩...但这不起作用(钩子永远不会被解雇,我现在已经丢失了代码。)

EDIT2:

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

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分: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编程书籍/文档可以涵盖这一点。原样,问题类似于过早优化,使用该语言会给你答案。