h = {a: "foo"}
h.fetch(:a, h.fetch(:b))
yields key not found: :b
It seems strange that Ruby evaluates the default value even when the key is found? Is there a way around this?
Edit: Apparently this behavior falls under the paradigm of lazy vs eager evaluation. Nearly all imperative languages use eager evaluation, while many functional languages use lazy evaluation. However some languages, such as Python (which was before last week the only language I knew), have lazy evaluation capabilities for some operations.
It seems strange that Ruby evaluates the default value even when the key is found? Is there a way around this?
The overwhelming majority of mainstream programming languages is strict, i.e. arguments are fully evaluated before being passed. The only exception is Haskell, and calling it mainstream is a bit of a stretch.
So, no, it is not really "strange", it is how (almost) every language works, and it is also how every single other method in Ruby works. Every method in Ruby always fully evaluates all its arguments. That is, why, for example defined? and alias cannot be methods but must be builtin language constructs.
However, there is a way to delay evaluation, so to speak, using blocks: the content of a block is only evaluated each time it is called. Thankfully, Hash#fetch does take a block, so you can just use
h.fetch(:a) { h.fetch(:b) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With