ในการเรียกใช้ method
in ruby
obj.method
in java
obj.method()
ซึ่งดูแล้วน่าจะเหมือนกัน
แต่ลองดูตัวอย่างนี้
class VCR
def initialize
@messages = []
end
def method_missing(method, *args, &block)
@messages << [method, args, block]
end
def play_back_to(obj)
@messages.each do |method, args, block|
obj.send(method, *args, &block)
end
end
end
class VCR มี method หลักๆอยู่อันเดียวคือ
play_back_to ส่วน method_missing
จะใช้กรณีที่มีการเรียกใช้ method ที่ไม่ได้มีการ definition ไว้
อธิบายการทำงานได้ดังนี้
initalize เรียกใช้เมื่อมีการ new object
โดยจะทำการ initialize Array ที่ชื่อ message
(เครื่องหมาย @ หมายถึง instance variable)
จากนั้นถ้ามีการ call method ที่ไม่ได้ประกาศไว้
ให้ทำการเก็บ list ของ method, param, block ไว้ใน message Array
กรณีที่ call playback ก็ให้นำ method ทั้งหมดที่เก็บไว้ใน
message Array ออกมาเรียกใช้กับ object ที่ pass มา
ลองดูการนำไปใช้
require 'src/vcr'
vcr = VCR.new
vcr.sub!(/Java/) { "Ruby" }
vcr.upcase!
vcr[11,5] = "Universe"
vcr << "!"
string = "Hello Java World"
puts string
vcr.play_back_to(string)
puts string
ผลลัพท์ที่ได้
Hello Java World
HELLO RUBY Universe!
อธิบายเพิ่มเติมสำหรับคนที่ยังไม่คุ้น syntax ruby
โดยหลังจากที่เรา new VCR object แล้ว
ก็เรียกใช้ method sub!, upcase, array assignment([]=), concat(<<)
ซึ่งทั้งหมดนี้ไม่ได้มีการประกาศไว้ใน VCR Class เลย
ดังนั้น method ทั้งหมดก็จะถูกเก็บไว้ใน messages array
จากนั้นเมื่อมีการเรียกใช้ play_back_to
ก็จะนำเอา method เหล่านี้ออกมาเรียกใช้กับ
String ที่ pass เข้าไป
sub! -> inplace substitution
upcase! -> inplace upper case
[11,5]="Universe" -> เป็นการแทน char ที่ตำแหน่ง 11 โดยแทนที่ 5 ตัวอักษร
<<"!" -> concat ต่อท้าย
ดูแล้ว ก็รู้สึกว่า language มัน dynamic ดีจัง
เขียนแล้วคงจะสนุกดี (เพราะมี choice ให้ creative ได้หลายแบบ)
แต่น่าจะปวดหัวพอสมควร สำหรับการใล่ code
ที่เขียนด้วย ruby
No comments:
Post a Comment