0

这里需要读取一个 json 文件并制作从一个类完成的变量并在另一个类中使用它们。到目前为止我所拥有的是

助手.rb

class MAGEINSTALLER_Helper
    #note nonrelated items removed
    require 'fileutils'
    #REFACTOR THIS LATER
    def load_settings()
        require 'json'
        file = File.open("scripts/installer_settings.json", "rb")
        contents = file.read
        file.close
        #note this should be changed for a better content check.. ie:valid json
        #so it's a hack for now
        if contents.length > 5 

            begin
                parsed = JSON.parse(contents)
            rescue SystemCallError
                puts "must redo the settings file"
            else    
                puts parsed['bs_mode']
                parsed.each do |key, value|
                    puts "#{key}=>#{value}"
                    instance_variable_set("@" + key, value) #better way?
                end
            end
        else
            puts "must redo the settings file"
        end
    end

    #a method to provide feedback simply 
    def download(from,to)
        puts "completed download for #{from}\n"
    end
end

在 Pre_start.rb 文件中调用

class Pre_start
    #note nonrelated items removed
    def initialize(params=nil)
        puts 'World'

        mi_h = MAGEINSTALLER_Helper.new

        mi_h.load_settings()
        bs_MAGEversion=instance_variable_get("@bs_MAGEversion") #doesn't seem to work
        file="www/depo/newfile-#{bs_MAGEversion}.tar.gz"
        if !File.exist?(file)
            mi_h.download("http://www.dom.com/#{bs_MAGEversion}/file-#{bs_MAGEversion}.tar.gz",file)
        else
            puts "mage package exists"
        end

    end
end

josn 文件是有效的 json 并且是一个简单的对象(注意有更多只是显示相关)

{
    "bs_mode":"lite",
    "bs_MAGEversion":"1.8.0.0"
}

我需要一个 json 设置文件的原因是我需要从 bash 脚本和后来的 php 脚本中提取设置。该文件是用于传递设置每个共享和需要匹配的公共线程。

现在我最终得到一个空字符串作为值。

4

3 回答 3

0

我们在工作中的代码中一直在做类似的事情。问题和解决方案是在代码的主要级别中正确使用变量和范围。我们使用 YAML,你使用 JSON,但想法是一样的。

通常,我们在主代码中定义一个常量,例如CONFIG,我们将 YAML 加载到该常量中,然后在我们需要的所有代码中都可以使用该常量。对你来说,使用 JSON 代替:

require 'json'

require_relative 'helper'

CONFIG = JSON.load_file('path/to/json')

此时CONFIG将可用于顶级代码和“helper.rb”代码。

作为另一种方法,只需将 JSON 加载到任一文件中即可。加载时间可以忽略不计,它仍然是相同的数据。

由于 JSON 数据在程序运行时应该是静态的,因此可以在 CONSTANT 中使用它。仅当数据因代码实例而异时,将其存储在实例变量中才有意义,当您从 JSON 或 YAML 类型的文件加载数据时,这是没有意义的。

另外,请注意我正在使用 JSON 类中的方法。不要通过你用来尝试将 JSON 复制到实例变量中的 rigamarole。

以剥离代码为例:

require 'fileutils'
require 'json'

CONTENTS = JSON.load_file('scripts/installer_settings.json')

class MAGEINSTALLER_Helper

  def download(from,to)

    puts "completed download for #{from}\n"

  end
end

class Pre_start

  def initialize(params=nil)

    file = "www/depo/newfile-#{ CONFIG['bs_MAGEversion'] }.tar.gz"
    if !File.exist?(file)
      mi_h.download("http://www.dom.com/#{ CONFIG['bs_MAGEversion'] }/file-#{ CONFIG['bs_MAGEversion'] }.tar.gz", file)
    else
      puts "mage package exists"
    end

  end
end

CONFIG可以在任一文件中初始化/加载,只需在需要访问内容之前从顶层执行。

请记住,Ruby 从第一个文件的顶部开始执行它并向下读取。和块之外的代码在def遇到时会被执行,因此一旦 Ruby 看到该代码,就会进行初始化。如果在您开始调用方法和创建类实例之前发生这种情况,那么您的代码会很高兴。classmoduleCONFIG

于 2013-10-16T23:17:37.513 回答
0

在这条线上:

    bs_MAGEversion=instance_variable_get("@bs_MAGEversion") #doesn't seem to work

instance_variable_get 没有从 mi_h 对象中检索,这是您的值的存储位置。您使用它的方式,该行相当于:

    bs_MAGEversion=@bs_MAGEversion

将其更改为 mi_h.instance_variable_get 将起作用。它也将是非常难看的红宝石。但我觉得这不是你所追求的。如果我没看错的话,你想要这一行:

    mi_h.load_settings()

在 Pre_start 对象中填充 @bs_MAGEversion 和 @bs_mode。Ruby 并不是这样工作的。与您在这里寻找的最接近的东西可能是 mixin,如下所述:

http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html

于 2013-10-16T23:21:08.857 回答
0

instance_variable_set是在类内创建变量MAGEINSTALLER_Helper。这就是您无法访问这些变量的原因。

您可以将其重构为一个模块,如下所示:

require 'fileutils'
require 'json'

module MAGEINSTALLER_Helper
  #note nonrelated items removed
  #REFACTOR THIS LATER
  def load_settings()

    content = begin 
      JSON.load_file('scripts/installer_settings.json')
    rescue
      puts 'must redo the settings file'
      {} # return an empty Hash object
    end

    parsed.each {|key, value| instance_variable_set("@#{key}", value)}
  end

  #a method to provide feedback simply 
  def download(from,to)
    puts "completed download for #{from}\n"
  end
end

class PreStart
  include MAGEINSTALLER_Helper
  #note nonrelated items removed
  def initialize(params=nil)
    puts 'World'

    load_settings # The method is available inside the class
    file="www/depo/newfile-#{@bs_MAGEversion}.tar.gz"
    if !File.exist?(file)
      download("http://www.dom.com/#{@bs_MAGEversion}/file-#{@bs_MAGEversion}.tar.gz",file)
    else
      puts "mage package exists"
    end
  end
end

我稍微重构了一下,变得更加 Rubish 风格。

于 2013-10-16T23:28:22.343 回答