Skip to content

Conversation

@nz
Copy link
Member

@nz nz commented Jan 14, 2026

OptionalHash enhances Hash by returning Option where appropriate.

Comment on lines 23 to 24
obj = super(key)
obj.nil? ? None() : Some(obj)
Copy link
Member

@h3h h3h Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm. These semantics seem slightly off to me. I think you want to retain nil as a valid value at a specific hash key.

I think this should check the key existence directly and go for None() in the case of a missing key, no?

Something like…

Suggested change
obj = super(key)
obj.nil? ? None() : Some(obj)
key?(key) ? Some(super[key]) : None()

The semantics are weird if it presumes to understand the value, at least according to my understanding…

>> h = {}
=> {}

>> h[:a] = 1
=> 1

>> h[:b] = nil
=> nil

>> h
=> {:a=>1, :b=>nil}

>> h[:b] # this is intentional and therefore a valid value
=> nil

>> h[:c] # this is where we want None() to play a part
=> nil

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know, that's a good point. Adding to the tests!

# h[:description] = { short: { text: "Nested hash" } }
# h.dig(:description, :short, :text) # => Some("Nested hash")
# h.dig(:description, :long) # => None()
def dig(*args)
Copy link
Member Author

@nz nz Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation is probably a disaster, I am interested in something properly recursive based on key checks. Although dig semantics will certainly blur the difference between nil as value and nil as non-existent value. So I'm torn.

Copy link
Member

@h3h h3h Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that probably requires defining our expectations for dig's semantics.

I would say: “traverse this nested set of keys and return the value at the final nested key, if it exists.”

In which case, the Optional treatment could break down to something like:

  • Until the given chain (ordered list) of keys are exhausted:
    • Try to access the current nested hash at the next nested key
      • If the key exists, and the value at the key is a Hash, and there are further keys in the chain, recurse on the value
      • If the key exists and there are no more keys in the chain, return Some(value)
      • Else return None()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants