Last active
September 23, 2016 20:00
-
-
Save albb0920/e3d419dae3ce8819e0ac522fe8da12ec to your computer and use it in GitHub Desktop.
Inject method accessor for specific Hash instance PoC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ==== | |
# PoC: dot access to specific hash instance | |
# === | |
x = {a: 1, b:2} | |
# override method_missing | |
original_method_missing = x.method(:method_missing) | |
x.define_singleton_method :method_missing do|name, *args, &block| | |
return x[name] if x.key? name | |
original_method_missing.bind(self).call(name, *args, &block) | |
end | |
puts "Can now access hash via method, x.a => #{x.a}" | |
begin | |
Marshal.dump(x) | |
rescue Exception => e | |
puts "But this breaks Marshal: #{e.class}: #{e}" | |
end | |
# solution: hook Marshal.dump() | |
x.instance_variable_set(:@_polluted_by_hash_magic_accessors, true) | |
original_marshal_dump = Marshal.method(:dump) | |
Marshal.define_singleton_method :dump do|*args| | |
obj = args[0] | |
if obj.instance_variable_defined? :@_polluted_by_hash_magic_accessors | |
obj.singleton_class.send :remove_method, :method_missing | |
obj.remove_instance_variable :@_polluted_by_hash_magic_accessors | |
end | |
original_marshal_dump.call(*args) | |
end | |
puts "Marshal now works: #{Marshal.load(Marshal.dump(x)).inspect}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The goal of this PoC is to reduce pollution to Hash.
Still needs:
Now I think this path is too hacky, maybe a wrapper object that is_a(Hash) would be a better solution.