it's just a sample of using ruby features

 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
70
71
72
73
74
75
# playing with ruby features
class Object
alias_method :__method_missing__, :method_missing
@@before_callbacks = Hash.new([])
@@after_callbacks = Hash.new([])
def method_missing(id, *args, &block)
name, target, type = id.to_s, '', nil
if name =~ /^before_([^>]*)/
target = $1.to_sym
type = :before
elsif name =~ /^after_([^>]*)/
target = $1.to_sym
type = :after
else
__method_missing__(id, *args, &block)
end
old_method = "__old__#{target}__"
if @@before_callbacks[target].empty? && @@after_callbacks[target].empty?
src = <<-END_SRC
alias_method :#{old_method}, :#{target}
def #{target}(*args, &block)
@@before_callbacks[:#{target}].each do |cb|
cb.call
end
#{old_method}(*args, &block)
@@after_callbacks[:#{target}].each do |cb|
cb.call
end
end
END_SRC
class_eval src, __FILE__, __LINE__
end
((type == :before) ?
@@before_callbacks :
@@after_callbacks)[target] << block
end
end
######################################################
module M
def print(arg)
puts arg
end
end
class C
include M
end
class D < C
before_print do
puts "[at #{Time.now}]"
end
after_print do
puts '*****************************'
end
end
D.new.print('Test print')
######################################################