#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    7
    Rep Power
    0

    YML and Hashery GEM


    Hey Guys I need some help. This post may be long, but I'll do my best to keep it to the details.

    I have a old environment I've been tasked with moving from 1.8.6 to 1.9.3

    This environment has a custom library that is used by a bunch of different ruby applications. The portion I'm having issue with right now is it used to use Facets/OpenCascade, so when it would load the YML you would get a object back(hash) that you could reference like a.b.c(or config.db)
    Anyhow Facets appears to have removed a bunch of this and gone to more core libs, but I found the gem Hashery and it seems like it will do what I want. But I can't not get the call to work. I keep getting wrong # of arguments on initialize. Below is my code and exception.

    yml:
    Code:
    db:
      database:    dbserver
      host:          sql01
      user:          user
      password:   password

    load_config.rb
    Code:
    config = YAML::load(IO.read(File.join(@path, "environment.yml")))
    config.merge!(YAML::load(IO.read(File.join(@path, "environments/#{@environment}.yml"))))
    @config = Hashery::OpenCascade.new(config)
    open_cascade.rb
    Code:
    class OpenCascade < OpenHash
    def initialize(*default)
      @read = {}
       leet = lambda { |h,k| h[k] = OpenCascade.new(&leet) }
       super(*default, &leet)
    end
    open_hash.rb
    Code:
    class OpenHash < CRUDHash
    
    def initialize(default=nil, safe=false, &block)
      @safe = safe
       super(*[default].compact, &block) <-- my debug throws the exception here
    end
    crud_hash.rb <-- there is no initialize method here, which is one of my confusion points. I don't understand what it's init'ing I can attach this class if need be.

    Exception:
    Code:
    C:/Ruby193/lib/ruby/gems/1.9.1/gems/hashery-2.0.1/lib/hashery/open_hash.rb:36:in `initialize': wrong number of argu
    ments (ArgumentError)
            from C:/Ruby193/lib/ruby/gems/1.9.1/gems/hashery-2.0.1/lib/hashery/open_hash.rb:36:in `initialize'
            from C:/Ruby193/lib/ruby/gems/1.9.1/gems/hashery-2.0.1/lib/hashery/open_cascade.rb:65:in `initialize'
    I'll provide whatever else is needed

    Comments on this post

    • Jacques1 agrees : excellent problem description
  2. #2
  3. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,911
    Rep Power
    1045
    Hi,

    this is both an error on your part and a bug in the library.

    The values you pass to the default parameter of OpenCascade#initialize are eventually sent to Hash#initialize (the built-in hash class of Ruby). Because OpenCascade inherits from OpenHash, OpenHash inherits from OpenCRUD, and OpenCRUD inherits from Hash.

    Those values are sent together with some block. However, Hash can only take either a value or a block (those are used for the default values). Hence the error.

    But this is not how OpenCascade works, anyway. You're supposed to pash the original hash to the [] method:

    Code:
    @config = Hashery::OpenCascade[config]
    The default parameter of Cascade#initialize are basically unused (and unusable) at the moment.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    7
    Rep Power
    0
    Thanks so much for explaining that Jacques1! I will try this out now.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    7
    Rep Power
    0
    Shouldn't I be able to reference the values the dotted way or am I totally missing it? i.e. conf.db.dabatabse

    this is what I'm trying to achieve, taken from open_cascade.rb
    Code:
      #   h = { :x => { :y => { :z => 1 } } }
      #   c = OpenCascade[h]
      #   c.x.y.z  #=> 1
    Code:
    @config = Hashery::OpenCascade[config]
    puts " conf dot #{@config.db.database.inspect}"
    returns conf dot {}
    
    puts "hash #{@config['db']['database'].inspect}"
    returns conf values "dbserver"
  8. #5
  9. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,911
    Rep Power
    1045
    Looks like you gotta use symbols as hash keys. Just prefix the keys in your YAML file (db, database, host, ...) with a colon.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    7
    Rep Power
    0
    Thanks again! Were you able to determine that by this line?
    Code:
     #   h = { :x => { :y => { :z => 1 } } }
     #   c = OpenCascade[h]
    or did something else clue you in? Just trying to pick up what I can
  12. #7
  13. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,911
    Rep Power
    1045
    I checked the difference between your hash and the example hash, and the only difference were the keys.

    Usually, Ruby methods operating on hashes should accept both string and symbol keys, because both have advantages and disadvantages. That together with the bug tells me that the library hasn't been written very carefully. But if it works now, you should be fine.

    Comments on this post

    • danman71 agrees : 100% helpful, great communication, concise and to the point. Thanks again!
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    7
    Rep Power
    0
    awesome thanks!

IMN logo majestic logo threadwatch logo seochat tools logo