将Ruby存储在YAML文件中

时间:2021-10-01 23:06:49

I've got an idea, but it's implications scare me. Perhaps you, dear reader, can help. :)

我有一个想法,但它的含义吓到我了。亲爱的读者,也许你可以提供帮助。 :)

The Setup

安装程序

I've created a Ruby-based CLI app that allows user configuration via a YAML file. In that file, there is scenario where the user can define pre and post "actions" that display a message (with some arbitrary, non-relevant code in-between). For example:

我创建了一个基于Ruby的CLI应用程序,允许用户通过YAML文件进行配置。在该文件中,存在用户可以定义显示消息的前后“动作”的情况(其间具有一些任意的,不相关的代码)。例如:

actions:
  - action
      # ...other keys...
      pre:
        message: 'This is the pre message'
        action: puts 'PRE COMMAND'
      post:
        message: 'This is the post message'
        action: puts 'POST COMMAND'

In this case, my app would output This is the pre message, evaluate the "pre" action (thus outputting PRE COMMAND), do some irrelevant stuff, output This is the post message, and finally evaluate the "post" action (thus outputting POST COMMAND).

在这种情况下,我的应用程序将输出这是预先消息,评估“预”动作(从而输出PRE COMMAND),做一些无关的东西,输出这是帖子消息,最后评估“post”动作(从而输出POST COMMAND)。

The Problem

问题

You can already guess the problem; it appeared when I used the word "evaluate". That's a scary thing. Even though this is a locally-run, client-centric app, the idea of eval'ing random Ruby is terrifying.

你已经猜到了问题;它出现在我使用“评估”这个词的时候。这是一件可怕的事情。即使这是一个以本地运行的,以客户为中心的应用程序,评估随机Ruby的想法也是可怕的。

Solution Idea #1

解决方案想法#1

The first idea was just that: eval the actions. I quickly destroyed it (unless one of you knows-more-Ruby-than-me types can convince me otherwise).

第一个想法就是:评估行动。我很快就把它摧毁了(除非你们其中一个人知道 - 比我更多的Ruby类型可以说服我)。

Solution Idea #2

解决方案理念#2

Do some "checking" (via Regexp, perhaps) to validate that the command is somehow "valid". That seems wildly large and difficult to contain.

做一些“检查”(可能通过Regexp)来验证命令是否以某种方式“有效”。这看起来非常庞大,难以控制。

Solution Idea #3

解决方案想法#3

Another idea was to wrap acceptable commands in data structures of my own (thus limiting the possibilities that a user could define). For instance, I might create an open_url action that safely validates and opens a URL in the default browser.

另一个想法是将可接受的命令包装在我自己的数据结构中(从而限制了用户可以定义的可能性)。例如,我可能会创建一个open_url操作,可以安全地验证并在默认浏览器中打开一个URL。

I like this idea, but it seems rather limiting; I'd have to define a zillion wrappers over time, it seems like. But perhaps that's the price you pay for safety?

我喜欢这个想法,但似乎相当有限;我不得不随着时间的推移定义一个包装好的包装器。但也许这就是你为安全付出的代价?

Your Turn

到你了

I appreciate any additional thoughts you have!

我很感激您的任何其他想法!

1 个解决方案

#1


0  

You'd probably be a lot better off writing a simple framework that allows for Ruby plugins than to glue together something out of YAML and snippets of code.

编写一个允许Ruby插件的简单框架,而不是将YAML和代码片段之间的东西粘合在一起,你可能要好得多。

You're right that "eval" is terrifying, and it should be, but sometimes it's the most elegant solution out of all possible inelegant solutions. I'd argue that this time is not one of those cases.

你是对的,“eval”是可怕的,它应该是,但有时它是所有可能的优雅解决方案中最优雅的解决方案。我认为这次不是其中之一。

It's not at all hard to write a very simple DSL in Ruby where you can express your configuration in code:

在Ruby中编写一个非常简单的DSL并不难,您可以在代码中表达您的配置:

action.pre.message = 'This is the pre message'
action.pre.command do
  puts "PRE COMMAND"
end

All this depends on is having a number of pre-defined structures that have methods like message= taking a string as an argument or command taking a block. If you want to get fancy you can write some method_missing handlers and make up things as you go along, allowing for maximum flexibility.

所有这些取决于具有许多预定义结构,这些结构具有诸如message =将字符串作为参数或采用块的命令之类的方法。如果你想得到想象,你可以编写一些method_missing处理程序并随着时间的推移进行组合,从而获得最大的灵活性。

You can see many examples of this, from your Rakefile to capistrano, and it usually works out a lot better than having a non-Ruby configuration file format with Ruby in it.

你可以看到很多这样的例子,从你的Rakefile到capistrano,它通常比使用Ruby的非Ruby配置文件格式要好得多。

#1


0  

You'd probably be a lot better off writing a simple framework that allows for Ruby plugins than to glue together something out of YAML and snippets of code.

编写一个允许Ruby插件的简单框架,而不是将YAML和代码片段之间的东西粘合在一起,你可能要好得多。

You're right that "eval" is terrifying, and it should be, but sometimes it's the most elegant solution out of all possible inelegant solutions. I'd argue that this time is not one of those cases.

你是对的,“eval”是可怕的,它应该是,但有时它是所有可能的优雅解决方案中最优雅的解决方案。我认为这次不是其中之一。

It's not at all hard to write a very simple DSL in Ruby where you can express your configuration in code:

在Ruby中编写一个非常简单的DSL并不难,您可以在代码中表达您的配置:

action.pre.message = 'This is the pre message'
action.pre.command do
  puts "PRE COMMAND"
end

All this depends on is having a number of pre-defined structures that have methods like message= taking a string as an argument or command taking a block. If you want to get fancy you can write some method_missing handlers and make up things as you go along, allowing for maximum flexibility.

所有这些取决于具有许多预定义结构,这些结构具有诸如message =将字符串作为参数或采用块的命令之类的方法。如果你想得到想象,你可以编写一些method_missing处理程序并随着时间的推移进行组合,从而获得最大的灵活性。

You can see many examples of this, from your Rakefile to capistrano, and it usually works out a lot better than having a non-Ruby configuration file format with Ruby in it.

你可以看到很多这样的例子,从你的Rakefile到capistrano,它通常比使用Ruby的非Ruby配置文件格式要好得多。