【问题标题】:Implement an existing scripting language for a dynamic OO program为动态 OO 程序实现现有脚本语言
【发布时间】:2010-06-22 14:10:01
【问题描述】:

我正在开发一个程序,该程序处理大量对象和数据。因为我可以通过对我的应用程序使用某种“API”来注入操作。由于应用程序本身管理对象等,我想知道如何实现。例如,Unity3D 和 Panda3D 引擎允许使用多种语言编写脚本,例如 ECMA 或 Python。我不是在寻找要投入的“游戏”脚本语言,而是关于如何支持各种脚本语言的指针。

为了论证,假设我的程序有属于 Cube 类的对象。立方体具有类方法,如旋转、移动、变换和颜色、中心、大小等属性。现在,我想让我的用户可以使用例如 JavaScript 来操作对象。然而,我的“核心”程序是用 Ruby 编写的。

  1. 我是否必须从头开始编写一个完整的包来评估用户代码及其语法(作为实现自己的 JavaScript 版本)?或者是否有现有的包、骨架、框架、gem 等?
  2. 我将如何实现安全性以仅将脚本语言提供给允许操作的类(例如,将类标记为“可操作”的属性)。

我一直想知道企业应用程序是如何做到这一点的(游戏引擎也是如此......),所以感谢您的帮助和反馈。

【问题讨论】:

    标签: javascript ruby api scripting middleware


    【解决方案1】:

    如果您的核心程序是用 Ruby 编写的,我不明白您为什么希望脚本使用 Ruby 以外的任何其他语言编写——除了沙盒(见下文)。

    我是否必须编写一个完整的包来从头开始评估用户代码及其语法(如实现自己的 JavaScript 版本)?

    不可以。您可以将许多软件包合并到您的程序中。如果您的程序是用 C 编写的,或者即使它提供了 C 接口,您的决定也很容易:编程语言 Lua 旨在轻松嵌入到 C 程序中。我至少做了几十次。

    我将如何实现安全性以仅将脚本语言提供给允许被操作的类(例如,将类标记为“可操作”的属性)?

    您可以通过设置对脚本可见的名称集合来做到这一点——作为一名编程语言专家,我会说您控制 环境(用于讨论名称访问的技术术语)。例如,在 Lua 的情况下,您将向每个用户的脚本提供一个环境,该环境允许用户准确地命名您希望用户拥有的功能,仅此而已。如果脚本无法命名,则无法使用。这项工作通常称为沙盒。 (例如,“将用户放在沙箱中,不要让他们出去。”)通过控制命名空间的沙箱在 Lua 之外的其他语言中很常见。

    我一直想知道企业应用程序是如何做到这一点的(游戏引擎也是如此......)

    我不知道如何简要地总结这个技巧以获得 SO 答案。但总体思路是:

    • 脚本语言有字节码解释器

    • 有一个精心设计的协议用于脚本和 C 之间的调用

    如需更深入的了解,请阅读罗伯托的书Programming in Luaearlier edition 在线免费。

    【讨论】:

    • 大声笑,我同意。我更喜欢 Ruby 的一切。但是,我从经验中知道,学习一门面向对象的语言并不是您在 24 小时内获得专业知识的东西。我的目标受众很可能已经知道 JavaScript。谢谢您的回答。它非常具有描述性和详细性。
    • 我认为人们喜欢 Ruby 是因为您可以在其中创建有限的 DSL(特定于领域的语言)。您能否让脚本以特定于您的应用的有限 Ruby 子集编写?
    • 其实我喜欢 Ruby 因为代码很有意义。更像是我想扩展应用程序的一部分,用户可以在应用程序内部进行调整和集成。由于这是一个普遍的问题,我不限制任何事情。
    【解决方案2】:

    我不确定我是否完全符合您的要求,但是像 RESTful 这样的方法对您有用吗? REST 通常被认为是客户端/服务器术语,但我认为其中一些想法也可能适用于此。

    基本概念可能是您通过 API 公开对象的表示形式(可能是 JSON 或 XML)。客户将获取这些表示,进行他们想要的任何更改,然后将修改后的版本提交回您的程序。您的程序将验证更改并(假设它们是合法的)应用它们。

    这似乎可以让您完全不知道所使用的脚本语言类型,应该灵活且易于用户理解,并为您提供一个清晰的位置来实施您的安全策略。

    顺便说一下,虽然我不知道这是否是可编写脚本的游戏引擎的工作方式,但我看到一些企业系统公开了与此类似的 API(尽管通常作为 Web 服务而不是接受用户编写的脚本)。

    【讨论】:

    • 感谢您的回答。这是否意味着我的对象应该以某种可访问的格式存在?有没有我可以阅读的这种实现的示例和方法?
    • 嗯,我的想法是基于 Rails 附带的标准 ActiveResource 库 (api.rubyonrails.org/classes/ActiveResource/Base.html)。它通常用于网络服务,就像我说的那样,但我认为没有理由不能采用类似的方法与用户提供的脚本进行交互。特别是如果您使用 Rails3 中的一些新 ActiveModel 模块,我认为它应该非常简单(yehudakatz.com/2010/01/10/…)。不过,我不知道有任何示例完全符合您的要求。
    猜你喜欢
    • 2019-07-23
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    相关资源
    最近更新 更多