1

Is there an API or how would one go about creating hash keys being accessible by dot(.) methods like if there was Array of objects.

Here is an example :

data = [
  {
    key1: 'value1',
    key2: 'value2'
  },
  {
    key1: 'valuex',
    key2: 'valuey'
  },
  ...
]

If I tried to do this :

data.collect(&:key1)

Would get this error :

NoMethodError: undefined method `key1' for #<Hash:0x007fc2a7159188>

This however works :

data.collect{|hs| hs[:key1]}

Just because its a symbol and not object property. Is there a way I could accomplish same behaviour with symbols as if they were object properties?

1
  • 1
    It might be worth noting that hs[:key1] doesn't call a key1 method on the hash but it calls the [] method with :key1 as an argument. Commented Sep 22, 2017 at 13:41

3 Answers 3

1

You can wrap those hashes into OpenStruct. Try using this code:

data.map! { |hsh| OpenStruct.new(hsh) }

data.first.key1 # => "value1"
Sign up to request clarification or add additional context in comments.

Comments

0

This is inspired by @spickerman's comment. It's something one can do but probably shouldn't do.

You can add your custom method to Ruby's Enumerable module:

module Enumerable
  def enum_send(:method, *args)
    send(:method) { |obj| obj.send(*args) }
  end
end

You can then call

data.enum_send(:collect, :"[]", :key1)  ## [value1, valuex..]

or something like

data.enum_send(:each, :delete, :key2)  ## [{key1: value1}, {key1: valuex}..]

Comments

0

You can wrap your objects with OpenStruct

require 'ostruct'

data.map { |it| OpenStruct.new(it) }.collect(&:key1)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.