Đôi khi bạn có thể đẩy Ruby vào cốc espressso. Hãy xem làm thế nào.
Dưới đây là một mô-đun FunNotFun ...
module FunNotFun
def fun
@method_type = 'fun'
end
def notfun
@method_type = 'not fun'
end
def method_added(id)
return unless @method_type
return if @bypass_method_added_hook
orig_method = instance_method(id)
@bypass_method_added_hook = true
method_type = @method_type
define_method(id) do |*args|
orig_method.bind(self).call(*args).tap do
puts "That was #{method_type}"
end
end
@bypass_method_added_hook = false
end
end
... mà bạn có thể sử dụng để mở rộng một lớp ...
class Thing
extend FunNotFun
fun
def f1
puts "hey"
end
notfun
def f2
puts "hey"
end
end
... với kết quả này:
Thing.new.f1
# => hey
# => That was fun
Thing.new.f2
# => hey
# => That was not fun
Nhưng hãy xem bên dưới dòng để biết cách tốt hơn.
Chú thích (xem câu trả lời bình thường) ít gặp rắc rối hơn và là thành ngữ Ruby thông thường, sẽ dễ dàng truyền đạt ý định của mã của bạn hơn. Dưới đây là làm thế nào để làm điều đó với chú thích:
module FunNotFun
def fun(method_id)
wrap_method(method_id, "fun")
end
def notfun(method_id)
wrap_method(method_id, "not fun")
end
def wrap_method(method_id, type_of_method)
orig_method = instance_method(method_id)
define_method(method_id) do |*args|
orig_method.bind(self).call(*args).tap do
puts "That was #{type_of_method}"
end
end
end
end
Khi sử dụng, chú thích đưa ra sau khi phương thức được định nghĩa, chứ không phải trước đây:
class Thing
extend FunNotFun
def f1
puts "hey"
end
fun :f1
def f2
puts "hey"
end
notfun :f2
end
Kết quả là như nhau:
Thing.new.f1
# => hey
# => That was fun
Thing.new.f2
# => hey
# => That was not fun
Nguồn
2011-10-12 23:01:28
ah, đây là những gì tôi đã có trong tâm trí –
Là cách tiếp cận đầu tiên thread-an toàn? –
@Semyon, Không nếu bạn có nhiều chủ đề thêm phương thức vào cùng một lớp cùng một lúc. Gần như mọi khi, việc thêm các phương thức được thực hiện chỉ bằng một luồng. –