StringIO

  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.
  • warning: realpath() [function.realpath]: SAFE MODE Restriction in effect. The script whose uid is 1005 is not allowed to access /tmp owned by uid 0 in /var/www/sites/sugree/codenone.com/subdomains/www/html/includes/file.inc on line 190.

บางที ruby กับ python ก็ดูจะเหมือนพี่น้องที่คลานตามกันมา
ลองดูที่ lew post ไว้ใน แนะนำโมดูลที่น่าสน (Standard Module)
ลองเขียนเป็น ruby บ้าง

require 'stringio'
f = StringIO.new("ascdef")
f.read(2) # => "as"
f.tell # => 2
f.seek(0)
f.read # => "ascdef"

sugree's picture

สงสัยอีกแล้ว มันจะรู้ได้ยังไงว่า f.tell นี้หมายถึง ตัวฟังก์ชั่นเอง หรือว่าให้เรียกฟังก์ชั่นนั้น

อย่าง Python นี่ชัดเจน ถ้าต้องการเรียกก็ต้องมี () ถ้าไม่มีก็เป็นแค่ pointer

apirak's picture

ในหนังสือ programming ruby เค้าบอกว่า

no other object can access an object’s instance variables.

ดังนั้น f.tell จึงเป็นการ call function เท่านั้นครับ ไม่ใช่ pointer
ถ้าต้องการให้มันเสมือนเรียกได้แบบ f.tell ก็เขียนแบบนี้ครับ

class StringIO
    def initialize(tell) 
        @tell = tell 
    end
 
    def tell
        @tell 
    end
end 
 
f = StringIO.new("function call") 
f.tell

หรือไม่ก็ทำง่ายๆ แบบนี้

class StringIO
    attr_reader :tell
 
    def initialize(tell) 
        @tell = tell 
    end
end 
 
f = StringIO.new("function call") 
f.tell

ถ้าต้องการให้มันเขียนได้ด้วย ก็ลองแบบนี้ครับ

class StringIO
    def tell=(new_tell) 
        @tell = new_tell 
    end 
end
 
f = StringIO.new() 
f.tell = "function call" 
f.tell

เวลากำหนดตัวแปลมันจะเป็น private โดยอัตโนมัติครับ ต้องมาทำกระบวนการข้างต้นเพื่อให้มันดูเหมือนตัวแปล public

Apirak

ปล. code ผมลอกมาจากหนังสือแต่พยายามแก้ให้เห็น f.tell จะได้อ่านง่ายหน่อย

sugree's picture

งั้นแปลว่าส่ง method ไปให้ฟังก์ชั่นอื่นไม่ได้ใช่มั๊ยครับ ต้องใช้ {} ครอบแทน นี่ผมเริ่มจะเข้าใจมันรึยังเนี่ย

veer's picture

ประมาณว่าจาก python แบบข้างล่างจะเปลี่ยนเป็น ruby ยังไงเปล่าครับ?

class X:
    def y(self):
        print 10
 
def func(p):
    p()
 
x = X()
 
func(x.y)

ผมก็นึกออกแต่ท่าที่ใช้ {} กะ Proc หละครับ

class X
  def y
    print "10\n"
  end
end
 
def func(p)
  p.call  
end
 
x = X.new 
 
func(Proc.new{x.y})

มีท่าอื่นอีกเปล่าครับ?

sugree's picture

yield ได้รึป่ะ

apirak's picture
class X
    def y
        print "10\n"
    end
end
 
def func
    yeild
end
 
x=X.new
func{x.y}

yeild เขียนง่ายๆ ประมาณนี้ครับ

def call_block
    put "Start of method"
    yield
    yield
    put "End of method"
end
call_block { puts "In the block" }

output จะออกมาประมาณนี้ครับ

Start of method
In the block
In the block
End of method
Apirak

apirak's picture
class StringIO { // Java code 
    private String _tell; 
    public void setTell(String newTell) { 
        _tell = newTell; 
    } 
} 
f = new StringIO(....); 
f.setTell("function call");

ถ้าเขียนด้วย java ก็จะเป็นแบบนี้ครับ

Apirak

syntax ของ ruby
สามารถเรียกใช้ method โดยไม่ต้องใส่วงเล็บได้ครับ

>> def say(n)
>>  n + 1
>> end
=> nil
>> say 10
=> 11
>> say 11
=> 12

การ implement ก้คงต่างกันครับ
อย่าง code ข้างบน เราประกาศ say ไว้โดยไม่มี class ครอบ
คำถามก็คือ say นั้นอยู่ใน scope ของใคร
ใน ruby, say เป็น method ที่อยู่ภายใต้ top level object

ลอง run ruby -e "puts self"
จะเห็นว่ามัน top level object มีชื่อว่า main

sugree's picture

อืม main นี่เหมือน python หน่อย เรื่อง scope พอจะเข้าใจแล้ว

ย้าย Codenone

ประกาศย้าย Codenone ไปใช้ Forum ของ Blognone แทนครับ ตามไปตั้งกระทู้ต่อได้ที่ Codenone Forum (รายละเอียดอ่านจากกระทู้ ย้าย Codenone ไปรวมกับ Blognone)

กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น