Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/1339820cd8f90eff0e600b260c2c69bf to your computer and use it in GitHub Desktop.
Save JoshCheek/1339820cd8f90eff0e600b260c2c69bf to your computer and use it in GitHub Desktop.
BLACK MAGIC IN RUBY!
# ========== 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!"
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"}
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