-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathmethod_swizzle.rb
69 lines (59 loc) · 1.59 KB
/
method_swizzle.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/usr/bin/env ruby
# Author : Emad Elsaid (https://github.com/blazeeboy)
def swap_methods(from_obj, from_method, to_obj, to_method)
from_alias = "#{from_method}_#{rand 1000}"
to_alias = "#{to_method}_#{rand 1000}"
# alias methods in both objects
from_obj.class.class_eval do
alias_method from_alias, from_method
end
to_obj.class.class_eval do
alias_method to_alias, to_method
end
# override methods and call aliases in both direction
from_obj.define_singleton_method(from_method) do |*params, &block|
to_obj.send(to_alias, *params, &block)
end
to_obj.define_singleton_method(to_method) do |*params, &block|
from_obj.send(from_alias, *params, &block)
end
end
# calling swap between two methods on two objects
# should swap them, so if you call obj1.method1
# will execute obj2.method2 and vice versa
obj1 = "this is my first string object"
obj2 = "this is my second string object"
swap_methods obj1, :to_s, obj2, :to_s
# this should print the second string
puts obj1.to_s
# and this should print the first one
puts obj2.to_s
# swapping String new method with
# other class new method, so whenever
# you create a new String an instance of
# the other class
class X
attr_accessor :value
def initialize(value)
@value = value
end
end
swap_methods String, :new, X, :new
x_instance = String.new "Heeeey"
puts x_instance.class
# this code will output the following lines:
#
# this is my second string object
#
# this is my first string object
#
# X
#
#
# it normally should be :
#
# this is my frist string object
#
# this is my second string object
#
# String