在Ruby中读取json并设置变量以在另一个类中使用

在Ruby中读取json并设置变量以在另一个类中使用,ruby,json,Ruby,Json,这里需要读取一个json文件,并从一个类生成变量,然后在另一个类中使用它们。到目前为止,我得到的是 helper.rb class MAGEINSTALLER_Helper #note nonrelated items removed require 'fileutils' #REFACTOR THIS LATER def load_settings() require 'json' file = File.open("script

这里需要读取一个json文件,并从一个类生成变量,然后在另一个类中使用它们。到目前为止,我得到的是

helper.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,并且是一个简单的对象(注意,这里有更多的只是显示相关的)

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


现在,我得到了一个空字符串作为值。

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

通常我们在主代码中定义一个常量,如
CONFIG
,我们将YAML加载到该常量中,然后该常量在我们需要的所有代码中都可用。对于您而言,请改用JSON:

require 'json'

require_relative 'helper'

CONFIG = JSON.load_file('path/to/json')
此时,顶级代码和“helper.rb”代码都可以使用
CONFIG

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

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

另外,请注意,我使用的是来自JSON类的方法。不要使用繁杂的程序将JSON复制到实例变量中

例如,剥离代码:

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

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

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

在这一行:

    bs_MAGEversion=instance_variable_get("@bs_MAGEversion") #doesn't seem to work
    mi_h.load_settings()
实例_变量_get未从存储值的mi_h对象中检索。按照您的使用方式,该行相当于:

    bs_MAGEversion=@bs_MAGEversion
将其更改为mi_h.instance_variable_get会起作用。它也将是难看的红宝石。但我觉得这不是你想要的。如果我读对了,您需要这一行:

    bs_MAGEversion=instance_variable_get("@bs_MAGEversion") #doesn't seem to work
    mi_h.load_settings()
在预启动对象中填充@bs_MAGEversion和@bs_模式。Ruby不是那样工作的。最接近您在这里寻找的东西可能是mixin,如下所述:


实例变量集
正在
MAGEINSTALLER\u 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

我对其进行了一点重构,使其更具红色风格。

我想我会遵循这一点,但还是有点混乱。您的意思是,在最上面的整个文件中放置
CONFIG
,因此当我通过帮助程序加载它时,它将可用于所有类?对ruby来说还是个新手,所以我还是会拿到我的霸王牌。这就是我的票,我喜欢它的发展方向。那么这更像是红宝石风格?传统知识