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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions