2

フレームワークを使用して Ruby で記述されたコマンド ライン ユーティリティがありますGLI。Ruby 自体を DSL として使用して、コマンド ライン ユーティリティをホーム ディレクトリに設定したいと考えています (Gemfileまたはと同様Rakefile)。

私はフォルダー lib/myapp にクラス ConfigData を持っています。クラスは次のようになります。

class ConfigData
  @@data = {}

  class ConfigItem
    def initialize
      @data = {}
    end
    def missing_method(name, *args)
      @data[name] = args[0]
    end
  end

  def self.add(section)
    item = ConfigItem.new()
    yield item
    @@data[section]=item
  end

end

今、私が持ちたいのは、Myappfile現在の作業フォルダーにある、できれば name の構成ファイルで、次の内容です

add('section1') do |i|
  i.param1 'Some data'
  i.param2 'More data'
end

このコードがclassendConfigData の間に含まれていた場合、正常に機能しました。しかし今は、アプリケーションを起動する作業フォルダーに配置したいと考えています。

classConfigDataとの間で require('./Myappfile')endを試しましたが、うまくいきません。rake のソースコードを読んでみましたが、よくわかりません。

これを解決する方法のヒントはありますか?

4

1 に答える 1

2

インスタンスのコンテキスト内でコードを評価するには、これが目的であり、メソッドが必要ですinstance_eval()。通常の eval は絶対に使用しないでください。これまで。とにかく、fingi ファイルをロードしてデータを取得する方法は次のとおりです。

config = ConfigData.new
config.instance_eval(File.read("Myconfig"))
#Access configuration data here from the config object

それは簡単です。この方法でオブジェクトを読み込んだ後、オブジェクトの値にアクセスできます。

警告: これはあまり安全ではありません。これは実際には大きなセキュリティ ホールです。安全なバージョンは次のとおりです。

f = Fiber.new {str = File.read("Myconfig"); $SAFE = 4; config = ConfigData.new; config.instance_eval(str); Fiber.yield config}
confdata = f.resume
#Access configuration data here from confdata.

これにより、外部コードが (一種の) サンドボックスで実行されるため、卑劣なことは何もできなくなります。


また、YAML 構成を使用しないのはなぜですか? 設定で RUBY_VERSION のようなコードを実行しpwdたり、RUBY_VERSION にアクセスしたりする必要がない限り、YAML ははるかにシンプルで安全であり、さらにフェイルプルーフです。

于 2012-12-23T15:08:37.313 に答える