def put(key, value = yield(get(key)))
      new_trie = @trie.put(Erlang.from(key), Erlang.from(value))
      if new_trie.equal?(@trie)
        return self
      else
        return self.class.alloc(new_trie, @default)
      end
    end
def put(key, value = yield(get(key)))
      new_trie = @trie.put(Erlang.from(key), Erlang.from(value))
      if new_trie.equal?(@trie)
        return self
      else
        return self.class.alloc(new_trie, @default)
      end
    end
Return a new `Map` with the existing key/value associations, plus an association
 between the provided key and value. If an equivalent key is already present, its
 associated value will be replaced with the provided one.

 If the `value` argument is missing, but an optional code block is provided,
 it will be passed the existing value (or `nil` if there is none) and what it
 returns will replace the existing value. This is useful for "transforming"
 the value associated with a certain key.

 Avoid mutating objects which are used as keys. `String`s are an exception:
 unfrozen `String`s which are used as keys are internally duplicated and
 frozen. This matches RubyHash's behaviour.

 @example
   m = Erlang::Map["A" => 1, "B" => 2]
   m.put("C", 3)
   # => Erlang::Map["A" => 1, "B" => 2, "C" => 3]
   m.put("B") { |value| value * 10 }
   # => Erlang::Map["A" => 1, "B" => 20]

 @param key [Object] The key to store
 @param value [Object] The value to associate it with
 @yield [value] The previously stored value, or `nil` if none.
 @yieldreturn [Object] The new value to store
 @return [Map]