Thursday, January 21, 2010

เล่น Lego

Lego เป็นของเล่นที่ดี แต่ราคาแพง สมัยเด็กๆจำได้ว่าอยากได้มาก ต้องรอจนมัธยมแล้ว แม่ถึงซื้อให้เล่น 1 ชุด โดยมีข้อแม้ว่าซื้อให้ ผมกับน้องสองคน ไม่ใช่ของใครคนใดคนหนึ่ง

พอโตขึ้นมามีลูกของตัวเอง ช่วงน้องปัณณ์อายุ 4 ขวบ อาเก่งกับอาหนึ่งซื้อ Lego ให้เป็นของขวัญ, ปรากฎว่าน้องปัณณ์ชอบของเล่นชิ้นนั้นมาก นั่นต่อ Lego ตามจินตนาการไปเรื่อย, หน้าที่พ่อก็เลยต้องคอยหา Input เข้าไปเรื่อยๆ เพื่อให้เกิดความท้าทายและไม่น่าเบื่อ (ตามกฎของ Flow)



ในกรณีของ Lego นี้, input มีอยู่สองสามแบบก็คือ
1. ซื้อชุดใหม่ให้เขา ให้เขาได้ตื่นเต้นกับแบบใหม่ๆ อันนี้ทำบ่อยๆไม่ดีแน่ เพราะราคามันสูงมากและถ้าได้มาง่ายไป มันจะไม่มีค่าเท่าไร
2. หา MOC (My Own Creation) ที่คนอื่นสร้างไว้มาให้เขาดู เขาจะได้เกิดแรงบันดาลใจ และเรียนรู้ว่ามันมีความเป็นไปได้ในการต่อเยอะแยะไปหมด
3. หาเนื้อหาใหม่ๆ ที่ทำให้เขาใช้ Lego เป็นเครื่องมือในการหมกมุ่นกับเนื้อหานั้นๆ เช่นช่วงวันเด็กผมพาไปปัณณ์ไปดูงาน Lego ที่เขาเอา Lego มาต่อเป็นเมืองจำลอง กลับบ้านมาก็เลยมีการทำฉากจำลองต่างๆกันบ้าง หรือแนะนำเกมส์ Spore ให้เขาเล่น ซึ่งพอเขาเล่น Lego เขาก็จะพยายามต่อเป็นสัตว์ประหลาดในเกมส์

อันนี้เป็นผลงาน MOC ของลูกชาย ที่ต่อเมื่อคืนนี้





ส่วนของพ่อได้ลำนี้ออกมา



หลังจากที่ลูกหมกมุ่นกับ Lego ได้เกือบ 1 ปี ตอนนี้ต่อมเก็บกดของพ่อเด็กเริ่มแตกแล้ว อันนี้เป็นสิ่งที่น่ากลัวมาก เพราะเราเป็นคนถือกระเป๋าเงิน, ลูกติด แต่มันไม่มีเงิน มันก็เลยซื้อไม่ได้ แต่ถ้าพ่อติด และพ่อมีเงิน อันนี้สิน่าหวาดเสียว

Related link from Roti

Tuesday, January 19, 2010

MultiMethod with Visitor Pattern

ต่อจากเมื่อวาน Link
อาจารย์โป้งได้อธิบายให้ฟังด้วยว่า วิธีหนึ่งที่เขานิยมใช้ implement multiple dispatch ใน Language ที่ support แต่ single dispatch ก็คือ Visitor Pattern (อาจารย์โป้งไม่ได้ใช้วิธีนี้)

ผมก็เลยเอาตัวอย่างเมื่อวานมาลองเขียนดู
เริ่มแรกก็คือ ให้เจ้า concrete animal ของเรามี accept method ที่รับ Visitor interface ก่อน
public interface Animal {
public void accept(IVisitor visitor);
}

public class Cat implements Animal {

@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}

}

public class Dog implements Animal {

@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}

}

จากนั้นก็ สร้าง Visitor Interface ที่มี method visit ครบทุก concrete animal ของเรา
public interface IVisitor {
public void visit(Cat cat);
public void visit(Dog dog);
}

ทดลอง feed อาหารโดยใช้ pattern ใหม่นี้
Cat cat = new Cat();
Dog dog = new Dog();

IVisitor bone = new IVisitor() {

@Override
public void visit(Cat cat) {
System.out.println("I don't like this. Meaw Meaw!!!");

}

@Override
public void visit(Dog dog) {
System.out.println("I 'm full. Hong Hong!!!");

}

};

IVisitor fish = new IVisitor() {

@Override
public void visit(Cat cat) {
System.out.println("I like this. Meaw Meaw!!!");

}

@Override
public void visit(Dog dog) {
System.out.println("Yes, I can eat this. Hong Hong!!!");

}

};

cat.accept(bone);
dog.accept(bone);

cat.accept(fish);
dog.accept(fish);

Related link from Roti

Monday, January 18, 2010

MultiMethod

เมื่อวันเสาร์ไป compkucamp มา เจออาจารย์โป้งเข้าก็เลยถามว่า ช่วงนี้ทำอะไรอยู่, อาจารย์โป้งก็ตอบว่ากำลัง implement multimethod บน c++ อยู่ ว่าแล้วก็ควักโน๊ตบุ๊คออกมาแสดง อาจารย์โป้งใช้ software ได้ผสมปนเปมาก เริ่มจากเปิด microsoft visual c++ ขึ้นมา จากนั้นก็ switch ไปใช้ terminal บน mac เพื่อใช้ django generate project files จากนั้นก็ show file content ให้ดูโดยใช้ textmate

หลังจากกลับมาบ้าน และส่งลูกเข้านอนหมดแล้ว เพื่อแก้ข้อสงสัยที่ฟังมา ก็เลยต้องเข้า wikipedia ไปหาอ่านเรื่อง Multimethod หรือ Multiple Dispatch บ้าง

ในการทำความเข้าใจกับเรื่องนี้ เราก็ควรจะเริ่มจาก basic สุดก่อนก็คือ Single Dispatch ซึ่งใช้ใน Java, C++, Smalltalk, Objective-C

ลองดู code นี้
public abstract class Animal {

public abstract void feed(Food food);

}

public abstract class Food {

}

public class Fish extends Food {

}

public class Bone extends Food {

}

public class Dog extends Animal {

@Override
public void feed(Food food) {
System.out.println("I 'm full. Hong Hong!!!");
}

}

public class Cat extends Animal {

@Override
public void feed(Food food) {
System.out.println("I 'm full. Meaw Meaw!!!");
}

public void feed(Bone food) {
System.out.println("I don't like this. Meaw Meaw!!!");
}

}



ถ้าลอง run แบบนี้ดู
public class Runme {

public static void main(String[] args) {
Animal a = new Dog();
Animal b = new Cat();

Bone bone = new Bone();
a.feed(bone);
b.feed(bone);

}

}


กรณีที่เป็น single dispatch ผลลัพท์ที่ได้ก็คือ
I 'm full. Hong Hong!!!
I 'm full. Meaw Meaw!!!

จะเห็นว่า single dispatch จะตัดสินใจเลือก method โดยดูแค่ว่าจะเลือกให้ class ไหนรับผิดชอบในการ handle การ call, โดยไม่ได้สนใจ type ของ arguments
ส่วน multiple dispatch มันจะเลือก method โดยดู type ของ arguments ด้วย
ถ้าทดลองนำ code ข้างบน ไป run ใน groovy ซึ่งเป็น multiple dispatch ผลลัพท์ทีได้ก็คือ
I 'm full. Hong Hong!!!
I don't like this. Meaw Meaw!!!

Related link from Roti