Skip to content

Add ability to seed/merge with a hash-like#10

Open
billdueber wants to merge 3 commits intomasterfrom
new_from_hashlike
Open

Add ability to seed/merge with a hash-like#10
billdueber wants to merge 3 commits intomasterfrom
new_from_hashlike

Conversation

@billdueber
Copy link
Copy Markdown

A hash-like is defined in the code to be something that responds to either #each_pair or both of #keys and #[].

The PR allows you seed a call to #new with a hash-like, for putting in initial values that you maybe got from somewhere else. It also allows merging in a hash like (where the argument overwrites whatever was there).

Canister itself fulfills the criteria for a hash-like, so you can also merge with another Canister.

Note that Canister (at least currently) doesn't allow numeric keys, so the incoming data can't, either.

# Seed with, or merge with, a hash
h = {a: 1, b: 2}
c = Canister.new(h)
c.a #=> 1

hello = proc{|name| "Hello #{name}"}
h2 = {b: 3, c: 3, d: hello}
c.merge(h2)
c.a #=> 1
c.b #=> 3
c.d.call("Bill") #=> "Hello Bill"

# Merge canisters
c2 = Canister.new do |can|
  can.register(:e) { 5 }
end

c2.merge(c)

c2.b #=> 3
c3.e #=> 5

[Also update rake version to address security update]

@billdueber billdueber requested a review from moseshll March 20, 2025 16:26
Comment thread lib/canister.rb
# Each value is wrapped in a `proc` and registered under the key.
# Note that Canister doesn't differentiate between symbols and
# strings for keys, so if your hashlike has keys of, e.g. both
# `"a"` and `:a` it won't work.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would recommend expanding on this and making explicit the fact that keys symbolizing to the same value will overwrite one another in unpredictable ways. It's hard to imagine a case in which this would be the expected or in any way legit usage so I would even put something like this in merge_from_hashlike

if hashlike.keys.map(&:to_sym).uniq.count != hashlike.count
  raise "you're gonna lose info!"
end

Comment thread lib/canister.rb
end
end
iter.each do |k, v|
blk = proc { v }
Copy link
Copy Markdown
Contributor

@moseshll moseshll Mar 25, 2025

Choose a reason for hiding this comment

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

What if v is a Proc? I can pass a proc like canister.register(:foo, &my_proc) but in a hashlike my proc is just going to be stored, and returned, as a proc -- maybe not what I was expecting. This may be a can of worms re developer intent.

I forgot about the hello example above, which is an argument for leaving procs alone instead of trying to "dereference" them inside Canister. I retract this comment.

Copy link
Copy Markdown
Contributor

@moseshll moseshll left a comment

Choose a reason for hiding this comment

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

Two comments I left inline, the one about symbol collisions should be addressed if only via an expanded comment. The second is worth thinking about and I'd welcome an opportunity to discuss it since we use the crap out of Canister but we don't often get a chance to talk about it.

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.

2 participants