Wednesday, November 30, 2005

คำถามดีๆ

คราวก่อนที่ post เรื่อง Higher Order Procedure ไป
bact ได้ post ถามว่า
method(op) กับ : ใน oper[:+]

นี่คือทำให้เราพิมพ์ + กับ - ได้ใช่มั๊ยครับ ?
คือ + กับ - เป็น object ด้วย

เป็นคำถามที่ดีจริงๆ
ผมชักชอบ blog มากขึ้นแล้วหล่ะ
คำถามใน blog ทำให้ความรู้เราเพิ่มขึ้น
(เพราะมันช่วยชี้ให้เห็นว่า เราลืมมองอะไรไปบ้างหรือเปล่า)
อย่างคราวก่อนที่ mk ถามเรื่อง "?" ที่อยู่หลัง ruby method
นั่นก็เป็นคำถามที่ดีเหมือนกัน
เพราะสมัยนั้นที่ผมมอง ruby code ผมไม่เคยตั้งคำถามเรื่องนั้นเลย
คำถามนั้นทำให้เราเห็นจุดอ่อนของเรา

กลับมาที่คำถามของ bact
ตอนแรกผมก็มองเหมือน bact (อาศัยความเคยชินจาก scheme)
+ มันต้องเป็น object ประเภท procedure แน่เลย
แต่กลายเป็นไม่ใช่
ลองดู code ต่อไปนี้
อันนี้ จาก scheme48

pphetra@[~]: scheme48
Welcome to Scheme 48 1.1 (made by pphetra on Sun Nov 13 15:03:12 ICT 2005).
Copyright (c) 1993-2004 by Richard Kelsey and Jonathan Rees.
Please report bugs to scheme-48-bugs@martigny.ai.mit.edu.
Type ,? (comma question-mark) for help.
> +
#{Procedure 52 +}
>

อันนี้ชัด + ใน scheme คือ procedure

ต่อไปจาก ruby บ้าง

pphetra@[~]: irb
irb(main):001:0> :+.class
=> Symbol
irb(main):002:0> 1.method(:+).class
=> Method
irb(main):003:0> 1.method(:+).call(2)
=> 3
irb(main):004:0> 1.method("+").class
=> Method
irb(main):005:0> 1.method("+").call(2)
=> 3
irb(main):006:0>

อา :+ จริงๆแล้วคือ symbol
ใน ruby, Object ทุกตัวจะมี method ที่ชื่อ method
คำสั่ง 1.method(:+) return ค่า
ออกมาเป็น method + ของ object 1
ซึ่งเราสามารถใช้ method call เพื่อสั่ง run จรีิงๆ
ปกติ method method จะรับ symbol เป็น parameter
แต่ก็สามารถส่งค่าเป็น String ให้ก็ได้เหมือนกัน

คำถามถัดไป ก็คือ แล้ว symbol คืออะไร
อืมม์ ยังไม่ค่อยแจ่มเหมือนกัน
แต่ดูตัวอย่างนี้ก่อน

pphetra@[~]: irb
irb(main):001:0> f1 = :pok
=> :pok
irb(main):002:0> f2 = :pok
=> :pok
irb(main):003:0> f1.object_id
=> 3918094
irb(main):004:0> f2.object_id
=> 3918094

เห็นในคำอธิบายเขาบอกว่า symbol จะมี instance เดียว
เสมอ ไม่ว่าจะอ้างถึงกี่ครั้งก็ตาม
หรือ ไม่ว่าจะอ้างจากคนละ context ก็ตาม

pphetra@[~]: irb
irb(main):001:0> module A
irb(main):002:1> $f1 = :pok
irb(main):003:1> end
=> :pok
irb(main):004:0> module B
irb(main):005:1> module C
irb(main):006:2> $f2 = :pok
irb(main):007:2> end
irb(main):008:1> end
=> :pok
irb(main):009:0> $f1.object_id
=> 3920142
irb(main):010:0> $f2.object_id
=> 3920142

Related link from Roti

No comments: