Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def put_in_f(hash, keys, value)
- if keys.empty?
- value
- else
- car, cdr = [keys[0], keys[1..]]
- hash.merge(car => put_in_f(hash[car], cdr, value))
- end
- end
- def extract(binding, ast)
- case ast.type
- when :SCOPE
- extract(binding, ast.children[2])
- when :CALL
- selv, methot, args = ast.children
- if methot == :[]
- keys, varname = extract(binding, selv)
- [[*keys, args.children[0].children[0]], varname]
- else
- raise NotImplementedError
- end
- when :DVAR
- [[], binding.local_variable_get(ast.children[0])]
- when :GVAR
- [[], eval(ast.children[0].to_s)]
- when :IVAR
- [[], binding.receiver.instance_variable_get(ast.children[0])]
- when :FCALL, :VCALL
- [[], binding.eval(ast.children[0].to_s)]
- else
- raise NotImplementedError, "ast.type #{ast.type} is not supported yet"
- end
- end
- def put_in(b, value)
- ast = RubyVM::AbstractSyntaxTree.of(b)
- keys, hash = extract(b.binding, ast)
- put_in_f(hash, keys, 150)
- end
- users = {
- ujihisa: {
- email: 'a@a.a',
- wallet: {
- money: 120,
- },
- },
- }
- users2 = put_in(-> { users[:ujihisa][:wallet][:money] }, 150)
- # this put_in behaves like
- # users.merge(ujihisa: users[:ujihisa].merge(wallet: users[:ujihisa][:wallet].merge(money: 150)))
- # to create an updated version of the given hash
- p users
- p users2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement