[#109207] [Ruby master Feature#18915] New error class: NotImplementedYetError or scope change for NotImplementedYet — Quintasan <noreply@...>
Issue #18915 has been reported by Quintasan (Michał Zając).
18 messages
2022/07/14
[ruby-core:109197] [Ruby master Feature#14564] `dig` opposite method
From:
"chrisseaton (Chris Seaton)" <noreply@...>
Date:
2022-07-13 16:00:03 UTC
List:
ruby-core #109197
Issue #14564 has been updated by chrisseaton (Chris Seaton).
Instead of different `dig` and `bury` tools, a 'lens' abstraction could combine the two.
```ruby
deep_hash = {a: {b: {c: {d: 100}}}}
p deep_hash.dig(:a, :b, :c, :d)
class Lens
def self.lens(*keys)
lens = Leaf.new(keys.pop)
lens = Node.new(keys.pop, lens) until keys.empty?
lens
end
class Node
def initialize(key, child)
@key = key
@child = child
end
def get(object)
@child.get object[@key]
end
def set(object, value)
@child.set object[@key], value
end
end
class Leaf
def initialize(key)
@key = key
end
def get(object)
object[@key]
end
def set(object, value)
object[@key] = value
end
end
end
lens = Lens.lens(:a, :b, :c, :d)
p lens.get(deep_hash)
lens.set deep_hash, 14
p lens.get(deep_hash)
```
----------------------------------------
Feature #14564: `dig` opposite method
https://bugs.ruby-lang.org/issues/14564#change-98336
* Author: nilcolor (Aleksey Blinov)
* Status: Open
* Priority: Normal
----------------------------------------
We have nice `dig` method that helps a lot.
Though we didn't have an opposite method that allows setting a value.
I know we already have these:
https://bugs.ruby-lang.org/issues/11747
https://bugs.ruby-lang.org/issues/13179
Both were closed because of name or lack of use cases. Let me promote the new name for this:
~~~ ruby
class Hash
def expand(*where, value)
where[0..-2].reduce(self) { |h, key|
h[key] = h[key] || {}
}[where[-1]] = value
self
end
end
{}.expand(:a, :b, :c, 42) # => {:a=>{:b=>{:c=>42}}}
{}.expand(:a, 0, :c, 42) # => {:a=>{0=>{:c=>42}}}
{a: {}}.expand(:a, :b, :c, 42) # => {:a=>{:b=>{:c=>42}}}
{a: {b: nil}}.expand(:a, :b, :c, 42) # => {:a=>{:b=>{:c=>42}}}
{a: {foo: "bar"}}.expand(:a, :b, :c, 42) # => {:a=>{:foo=>"bar", :b=>{:c=>42}}}
{a: {b: "wat"}}.expand(:a, :b, :c, 42) # => TypeError: no implicit conversion of Symbol into Integer
class Array
def expand(*where, value)
where[0..-2].reduce(self) { |a, idx|
a[idx] = a[idx] || []
}[where[-1]] = value
self
end
end
[].expand(2, 1, 3, "?") # => [nil, nil, [nil, [nil, nil, nil, "?"]]]
[1, [0, 2], []].expand(1, 1, "BAM") # => [1, [0, "BAM"], []]
[1, [0, 2], []].expand(2, 0, "BAM") # => [1, [0, 2], ["BAM"]]
~~~
Use cases: working with deeply nested structures, used as parameters (`params[:a][:nested][:some_id] = 42`).
In general, I think it's mostly useful for Hashes. Though having this on Array may be useful as well.
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>