Last active
March 24, 2018 22:06
-
-
Save JoshCheek/1339820cd8f90eff0e600b260c2c69bf to your computer and use it in GitHub Desktop.
BLACK MAGIC IN RUBY!
This file contains 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
# ========== READ THIS LAST ========== | |
# It prob won't make sense, anyway, as there's a lot of implicit nuance. | |
# I don't even fully understand the flags I'm setting it to. | |
public def to_s! | |
require 'fiddle' | |
Fiddle::Pointer.new(2*object_id)[0, 16] = | |
[5373957, 2*String.object_id].pack('q2') # flags & class | |
end | |
# ========== SETUP ========== | |
# An instance of a class with one ivar | |
class SomeClass | |
attr_accessor :some_var | |
end | |
some_obj = SomeClass.new | |
some_obj.some_var = 1205329432411354807 # found with: "Omg wat!".unpack("q")[0] >> 1 | |
# ========== BLACK MAGIC ========== | |
some_obj # => #<SomeClass:0x007fa0f3032500 @some_var=1205329432411354807> | |
some_obj.to_s! | |
some_obj # => "omg wat!" |
This file contains 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
require 'fiddle' | |
class Method | |
def self=(obj) | |
ptr = Fiddle::Pointer.new object_id << 1 | |
ptr = Fiddle::Pointer.new ptr[040, 8].unpack('q')[0] | |
ptr[0, 8] = [obj.object_id*2].pack('q') | |
end | |
end | |
class A | |
def initialize(a) | |
@a = a | |
end | |
def to_h | |
instance_variables.map { |v| [v, instance_variable_get(v)] }.to_h | |
end | |
end | |
class B | |
def initialize(b) | |
@b = b | |
end | |
end | |
# JavaScripters won't be impressed, but you can't normally do this in Ruby! | |
a = A.new 'aye' # => #<A:0x007fcd091513b8 @a="aye"> | |
b = B.new 'bee' # => #<B:0x007fcd091510c0 @b="bee"> | |
to_h = a.method :to_h # => #<Method: A#to_h> | |
to_h.call # => {:@a=>"aye"} | |
to_h.self = b | |
to_h.call # => {:@b=>"bee"} |
This file contains 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
require 'fiddle' | |
class Proc | |
def bind(obj) | |
bound = dup | |
ptr = Fiddle::Pointer.new bound.object_id << 1 | |
ptr = Fiddle::Pointer.new ptr[040, 8].unpack('q')[0] | |
ptr[0, 8] = [obj.object_id*2].pack('q') | |
bound | |
end | |
end | |
A = Class.new { define_method(:initialize) { |a| @a = a } } | |
B = Class.new { define_method(:initialize) { |b| @b = b } } | |
to_h = Proc.new do | |
instance_variables.map { |v| [v, instance_variable_get(v)] }.to_h | |
end | |
a = A.new 'aye' # => #<A:0x007fa794001480 @a="aye"> | |
b = B.new 'bee' # => #<B:0x007fa794001188 @b="bee"> | |
[to_h.bind(a), to_h.bind(b)].map &:call # => [{:@a=>"aye"}, {:@b=>"bee"}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment