Tags:
Forums: 

พอดีตอนนี้ที่ทำงานกำลังพยายามเขียน Plugin ExtJS โดยพยายามให้เป็น Convention over Configuration พยายามแทรกเข้าไปกับ model เลย ตอนนี้การสร้าง table ยังใช้การประกาศตัวแปรขึ้นมาอยู่ แต่หันไปเห็น belong_to :table, has_many :tables เลยอยากสร้าง method แบบนี้ได้บ้าง

พยายามเลียนแบบ ActiveRecord::Base อยู่พักใหญ่ แต่ได้ความว่าน่าจะใช้ self เพื่อทำให้เป็น class method แต่ก็ยังไม่สำเร็จ

class Foo
@name

  def self.included(base)
    base.extend(ClassMethods)
  end

  def x
    puts @name
  end

  def self.y(name)
    @name = name
    puts "y"
  end

  def self.z
    puts "z"
  end
end

class Goo < Foo
  z
  y :goo
end

กว่าจะทำให้ Goo รู้จัก z ได้แทบแย่ แต่พอทดลอง


g = Goo.new
=> #

ตอนนี้เริ่มเอะใจว่าทำไมมันไม่ puts "z" แต่ก็ลองต่อไป


g.x
nil
=> nil

ที่นี้ชัดเลยว่ามันไม่ยักกะใส่ค่าให้ @name ตอนนี้เลยมืด ∞ ด้านเลยครับ

Apirak.com Panatkool

ps. ใน blognone ใช้ Module Geshi ได้หรือเปล่าครับ

Get latest news from Blognone
By: mk
FounderAndroid
on 12 July 2008 - 02:00 #58320
mk's picture

เออผมลืมเรื่อง Geshi สนิทเลยแฮะ

By: pphetra
Writer
on 14 July 2008 - 12:29 #58507


def self.y(name)
@name = name
..
end

ตัวแปร @name ข้างบนมันอยู่ใน scope ของ Class Instance variable ซึ่งเป็นคนละ scope กับ @name ที่อยู่ใน method x

ใน class method เราไม่สามารถ access พวก instance variable ได้
วิธีทำที่ไกล้เคียงกับที่ apirak ยกตัวอย่างมาก็คือ ใช้ closure ช่วย

class Foo
def self.y(name)
define_method :x do
name
end
end
end

class Goo < Foo
y :goo
end

g = Goo.new
=> #
g.x
:goo

ตรง define method เขียนให้สั้นลงแบบนี้ก็ได้

define_method :x, lambda {name}

By: sid
Writer
on 14 July 2008 - 16:12 #58514

แอบสงสัยอย่างหนึ่งตรง self.y ใน class Foo ที่ทำให้ class Goo สามารถสั่ง

y :goo

ถ้าจะทำแบบนี้ได้ y ต้องกำหนดเป็น class method อย่างเดียวเลยใช่มั้ยครับ พอดีลองไปไล่ดู Validation ใน ActiveRecord ก็เห็นพวกคลาสอย่าง validate_presence_of สร้างเป็น instance method หรือจริง ๆ แล้วเค้าเอาพวกนี้ไปประกอบกับคลาส Base ให้เป็น class method ทีหลังครับ

By: pphetra
Writer
on 14 July 2008 - 17:23 #58524 Reply to:58514

ลองทำโปรแกรมข้างบนให้อยู่ใน pattern เดียวกับที่ validates_presence_of ใช้ดูนะครับ

เริ่มด้วยการประกาศ module

module MyDSL
def self.included(klass)
klass.extend ClassMethods
end

module ClassMethods
def y(name)
define_method :x, lambda { name }
end
end
end

เวลาใช้

class Foo
include MyDSL
end

class Goo < Foo
y :goo
end

จริงถ้าไม่อยากเยิ่นเย้อ ก็ไป include ไว้ใน Goo ตรงๆ ก็ได้
เช่น

class Goo
include MyDSL
y :goo
end

By: sid
Writer
on 14 July 2008 - 18:48 #58535 Reply to:58524

ขอบคุณมากครับ

ตอนแรกมีสงสัยเรื่อง include / extend ด้วย แต่พอไปอ่าน Extending your include knowledge of Ruby แล้ว ก็ไขข้อข้องใจไปได้

By: apirak
iPhoneUbuntu
on 15 July 2008 - 00:06 #58564 Reply to:58524

ขอบคุณครับ :)

Apirak.com panatkool

By: mk
FounderAndroid
on 14 July 2008 - 16:46 #58519
mk's picture

เปิด GeSHi ให้แล้วนะครับ รายละเอียดดูใน group