Skip to content

Ruby - Centroid::Config vs Hash inadequacies #66

@thorncp

Description

@thorncp

If a method uses a hash to handle optional arguments, we cannot currently give it a Centroid::Config instance and expect it to work. The case that we ran into is as follows, but there are more if we want to go into them.

require 'centroid'
config = Centroid::Config.new('{}')

def doit(properties = {})
  properties["a_key"] ||= "default value"
  p properties
rescue => e
  p e.message
end

doit # => {"a_key"=>"default value"}
doit({}) # => {"a_key"=>"default value"}
doit(config) # => "Centroid::Config instance does not contain key: a_key"

One workaround on the calling side is to have the method be aware that Centroid exists, and perform checks to determine if it's dealing with a Centroid::Config instance. This could also do is_a?(Hash), is_a?(Centroid::Config), etc., but it will always have the knowledge that Centroid exists (by either Centroid::Config or raw_config).

require 'centroid'
config = Centroid::Config.new('{}')

def doit(properties = {})
  properties = properties.raw_config if properties.respond_to?(:raw_config)
  properties["a_key"] ||= "default value"
  p properties
end

doit # => {"a_key"=>"default value"}
doit({}) # => {"a_key"=>"default value"}
doit(config) # => {"a_key"=>"default value"}

A workaround on the library side could be to start implementing Hash methods to give the appearance of actually being a Hash. (this is not a good idea)

I think a better idea would be to implement the to_h method that simply returns a hash representation, and calling code can rely on that. This moves the code away from knowing anything about Centroid, and just expects you to provide something that can become a Hash.

require 'centroid'
config = Centroid::Config.new('{}')

class Centroid::Config
  def to_h
    raw_config.dup
  end
end

def doit(properties = {})
  properties = properties.to_h # noop for Hash instances
  properties["a_key"] ||= "default value"
  p properties
end

doit # => {"a_key"=>"default value"}
doit({}) # => {"a_key"=>"default value"}
doit(config) # => {"a_key"=>"default value"}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions