เมธอด ในภาษา Ruby

27 December 2019

ในบทนี้ เราจะพูดเกี่ยวกับเมธอด คุณจะได้เรียนรู้เกี่ยวกับการสร้างและใช้งานเมธอดในภาษา Ruby

เมธอดคืออะไร

ในการเขียนโปรแกรมเชิงวัตถุ (OOP) เมธอดเป็นกระบวนการที่เกี่ยวข้องกับออบเจ็ค โดยทั่วไปแล้วออบเจ็คนั้นจะประกอบไปด้วยข้อมูลและเมธอดสำหรับจัดการข้อมูลดังกล่าว และเนื่องจาก Ruby นั้นเป็นภาษาที่เป็นออบเจ็คอย่างสมบูรณ์ ทุกเมธอดที่สร้างขึ้นนั้นเป็นส่วนหนึ่งของออบเจ็ค โดยทั่วไปแล้วเมธอดที่เราสร้างใน Ruby-toplevel นั้นจะอยู่ภายใต้ออบเจ็คจากคลาส Object

ในบทนี้เราจะพูดถึงการสร้างเมธอดที่มีวัตถุประสงค์เหมือนกับฟังก์ชันในภาษาอื่นๆ เช่น ภาษา Python หรือภาษา PHP (เมธอดที่ไม่ขึ้นกับออบเจ็คใดๆ) และอย่างที่เราได้บอกไปว่าเมธอดนั้นกระบวนการทำงาน ดังนั้นเราสามารถใช้เมธอดเพื่อรวบรวมโค้ดสำหรับทำงานบางอย่างได้ และที่สำคัญเราสามารถเรียกใช้งานเมธอดซ้ำๆ ได้ โดยที่ไม่ต้องเขียนโค้ดทั้งหมดใหม่

การสร้างและเรียกใช้งานเมธอด

ทุกเมธอดในภาษา Ruby นั้นจะต้องถูกสร้างก่อนที่คุณจะสามารถเรียกใช้งานมันได้ นี่เป็นรูปแบบของการสร้างเมธอดในภาษา Ruby

def method_name (param1, param2, ...)
    statements
end

เพื่อสร้างเมธอดเราใช้คำสั่ง def ตามด้วยชื่อของเมธอด method_name ชื่อของเมธอดนั้นมีกฏการตั้งเหมือนกับตัวแปร นั่นคือสามารถประกอบไปด้วยตัวอักษร ตัวเลข และเครื่องหมาย underscore (_) แต่ไม่สามารถขึ้นต้นด้วยตัวเลขได้

ต่อมาเป็นรายการอาร์กิวเมนต์ของเมธอดที่อยู่ภายในวงเล็บ ( และ ) อาร์กิวเมนต์คือตัวแปรที่ประกาศสำหรับนำมารับค่าที่ส่งเข้ามาในเมธอด หลังจากนั้นเป็นส่วนสำหรับกำหนดคำสั่งทำงานภายในเมธอด และเราจบการประกาศเมธอดด้วยคำสั่ง end นี่เป็นตัวอย่างการสร้างเมธอดในภาษา Ruby

def hello
    puts "Hello Ruby"
end

def add(a, b)
    a + b
end

ในตัวอย่าง คุณได้เห็นการสร้างเมธอดอยู่ด้วยกันสองแบบ เมธอด hello นั้นเป็นเมธอดที่ไม่มีอาร์กิวเมนต์ และสำหรับเมธอดไม่มีอาร์กิวเมนต์ เราสามารถละเว้นวงเล็บออกไปได้ และเมธอดที่สองคือเมธอด add เมธอดนี้มีสองอาร์กิวเมนต์คือ a และ b โดยเมธอดนี้ส่งค่ากลับเป็นผลรวมของตัวเลขทั้งสอง

หลังจากเมธอดได้ถูกสร้าง เราสามารถเรียกใช้งานเมธอดด้วยชื่อของมันได้ ตามด้วยการส่งค่าให้กับอาร์กิวเมนต์ของเมธอดดังนี้

hello()
puts add(1, 3)

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Hello Ruby
1 + 3 = 4

จากในตัวอย่าง บรรทัดแรกเราเรียกใช้งานเมธอด hello และเนื่องจากเมธอดนี้ไม่มีอาร์กิวเมนต์ เราไม่จำเป็นต้องส่งอาร์กิวเมนต์เข้าไปยังเมธอด แต่ยังคงต้องใส่วงเล็บหลังชื่อเมธอดในตอนเรียก ส่วนเมธอด add นั้นมีสองอาร์กิวเมนต์ เราจำเป็นต้องส่งค่าเข้าไปในเมธอดตามจำนวนอาร์กิวเมนต์ที่เมธอดมี

และเนื่องจากเมธอด add มีอาร์กิวเมนต์ที่กำหนดไว้สองตัวคือ a และ b ดังนั้นในการเรียกใช้เราต้องส่งค่าสำหรับอาร์กิวเมนต์ทั้งสอง ในตัวอย่างนั้นจะเป็น 1 และ 3 โดยค่าทั้งสองนี้จะถูกส่งเข้าไปผ่านอาร์กิวเมนต์ a และ b ตามลำดับ

อย่างไรก็ตาม ในการเรียกใช้เมธอดในภาษา Ruby คุณสามารถละเว้นการใส่วงเล็บในส่วนอาร์กิวเมนต์ของเมธอดได้ ยกตัวอย่างเช่น

hello
add 1, 3

สำหรับเมธอดที่ไม่มีอาร์กิวเมนต์เมื่อทำเช่นนี้ ก็จะเหลือเพียงชื่อของเมธอดเท่านั้น ส่วนเมธอดที่มีอาร์กิวเมนต์นั้น เราจะต้องใช้ช่องว่างเพื่อคั่นระหว่างชื่อของเมธอดและอาร์กิวเมนต์ที่ส่งเข้าไปยังเมธอด

นั่นเป็นเหตุผลว่าทำไมเราสามารถเรียกใช้งานเมธอด puts หรือเมธอด p ในตัวอย่างก่อนหน้าโดยไม่ใส่วงเล็บได้ ดังในโค้ดต่อไปนี้

puts "Hello", "Ruby"
puts("Hello", "Ruby")

จากในตัวอย่างนั้น โค้ดทั้งสองบรรทัดให้ผลลัพธ์เหมือนกัน แต่ในการเรียกใช้เมธอดโดยการใส่วงเล็บนั้น ชื่อของเมธอดและวงเล็บต้องติดกับวงเล็บเสมอ (ไม่มีช่องว่างระหว่างชื่อและวงเล็บ) ไม่เช่นนั้นจะทำให้โปรแกรมเกิดข้อผิดพลาดขึ้น เพราะ Ruby จะไม่สามารถแยกแยะได้ว่านั่นเป็นการเรียกใช้งานเมธอด

อย่างไรก็ตาม สำหรับการเรียกใช้งานเมธอดแบบไม่ใส่วงเล็บนั้น เรานิยมใช้กับเมธอดที่ไม่มีอาร์กิวเมนต์เท่านั้น เพื่อลดความสับสนและทำให้โปรแกรมอ่านง่าย ยกเว้นเมธอด puts และ p เนื่องจากเมธอดเหล่านี้ถูกใช้งานบ่อย เราจึงนิยมใช้แบบไม่ใส่วงเล็บแทน

เมธอดกับการส่งค่ากลับ

ทุกเมธอดในภาษา Ruby นั้นมีการส่งค่ากลับเสมอ โดยทั่วไปแล้วคำสั่งหรือนิพจน์สุดท้ายที่ถูกประมวลผลในเมธอดจะเป็นค่าที่ส่งกลับของเมธอด มาดูตัวอย่าง

def add(a, b)
    a + b
end

เราได้ประกาศเมธอด add สำหรับหาผลรวมของตัวเลขสองตัว และเนื่องจากคำสั่งสุดท้ายที่เมธอดประมวลผลคือ a + b ดังนั้นค่าดังกล่าวจึงเป็นค่าส่งกลับจากเมธอด และจากตัวอย่างด้านบนนั้นให้ผลลัพธ์เช่นเดียวกันกับการใช้คำสั่ง return ส่งค่ากลับ

def add(a, b)
    return a + b
end

จากทั้งสองตัวอย่างนั้นให้ผลลัพธ์ที่เหมือนกัน ในภาษา Ruby ถ้าหากคุณต้องการส่งค่ากลับในตอนท้ายของเมธอด คุณสามารถละเว้นคำสั่ง return ออกไปได้

นอกจากนี้คุณยังสามารถใช้คำสั่ง return เพื่อบังคับให้เมธอดส่งค่ากลับในทันที นั่นหมายความว่าเมื่อโปรแกรมพบกับคำสั่ง return การทำงานในเมธอดจะจบลง และโปรแกรมทำงานต่อไปในจุดที่เรียกใช้เมธอด ดังตัวอย่างต่อไปนี้

def divide(a, b)
    if b == 0
        return nil
    end
    a / b
end

p divide(1, 0)      # => nil
p divide(10, 2)     # => 5

ในตัวอย่าง เราได้สร้างเมธอด divide ซึ่งเป็นเมธอดสำหรับหารตัวเลขและส่งผลลัพธ์กลับไป อย่างไรก็ตาม ในการหารตัวเลขนั้นเราจะต้องตรวจสอบก่อนว่าตัวหารต้องไม่เป็นศูนย์ และเราส่งค่ากลับเป็น nil ถ้าหากตัวหารเป็นศูนย์ และเราจะเป็นต้องใช้คำสั่ง return เพื่อสั่งให้เมธอดส่งค่ากลับและจบการทำงาน ถ้าหากเราไม่ใส่คำสั่ง return ในคำสั่งเงื่อนไข if โปรแกรมจะทำงานในนิพจน์ a / b ต่อ

def divide(a, b)
    if b == 0
        return nil
    end
    return a / b
end

ในความเป็นจริงแล้ว คุณสามารถใส่คำสั่ง return ในทุกที่ที่คุณต้องการจะส่งค่ากลับได้ แต่ในทางปฏิบัติแล้ว ถ้าหากค่าที่ต้องการส่งกลับนั้นเป็นค่าที่ได้จากคำสั่งสุดท้ายของเมธอด เรามักจะละเว้นเพื่อความรวดเร็วและกระชับในการเขียนโปรแกรม

เมธอดกับการนำกลับมาใช้งานใหม่

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

def add(a, b)
    a + b
end

puts add(1, 2)
puts add(3.2, 1.4)
puts add(-10, 3)

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

3
4.6
-7

ในตัวอย่างเป็นเมธอด add เช่นเดิม แต่ในครั้งนี้เราเรียกใช้งานเมธอดนี้สามครั้ง และแน่นอนว่าเราได้นำเมธอดกลับมาใช้ใหม่โดยไม่จำเป็นต้องเขียนนิพจน์ 1 + 2, 3.2 + 1.4 และ -10 + 3 สิ่งที่เราทำก็คือรู้จักชื่อของเมธอดและทราบว่ามันใช้งานอย่างไร

ในตอนนี้ให้คุณลองจินตนาการว่านอกจากเมธอดสำหรับการบวกเลขง่ายๆ แล้วมันสามารถเป็นอะไรได้อีก ต่อไปมาดูเมธอดสำหรับคำนวณเกรดกัน โดยเราจะนำคะแนนของนักเรียนนั้นใส่เข้าไปในเมธอดและได้เกรดออกมา

grade_calculator.rb
def cal_grade(score)
    if score >= 80
        "A"
    elsif score >= 70
        "B"
    elsif score >= 60
        "C"
    elsif score >= 50
        "D"
    else
        "F"
    end
end

print "How many student to calculate?: "
n = gets.chomp.to_i
for i in (1..n)
    print "#{i}. Enter score: "
    sc = gets.chomp.to_i
    puts "Grade #{cal_grade(sc)}"
end

ในตัวอย่าง เป็นโปรแกรมคำนวณเกรดจากคะแนนของนักเรียนที่ใส่เข้ามาผ่านทางคีย์บอร์ด ตามจำนวนของนักเรียนที่ได้ระบุไปในการรับค่าครั้งแรก

def cal_grade(score)
    if score >= 80
        "A"
    elsif score >= 70
        "B"
    elsif score >= 60
        "C"
    elsif score >= 50
        "D"
    else
        "F"
    end
end

เราได้สร้างเมธอด cal_grade สำหรับคำนวณหาค่าเกรดโดยรับอาร์กิวเมนต์เป็นคะแนนเข้ามาผ่านทางตัวแปร score และเราใช้คำสั่งเลือกเงื่อนไข if เพื่อตรวจสอบว่าคะแนนที่ส่งเข้ามานั้นควรจะได้เกรดอะไร และส่งค่ากลับเป็นเกรดที่ตรงกับช่วงของคะแนนกลับไป

ต่อมาเป็นการเรียกใช้งานเมธอด cal_grade โดยการรับค่าคะแนนจากทางคีย์บอร์ด จะเห็นว่าเราสามารถเรียกใช้งานเมธอดนี้กี่ครั้งก็ได้ตามจำนวนนักเรียนที่เรามีและต้องการจะคำนวณเกรด

นี่เป็นผลลัพธ์ของโปรแกรมเมื่อเราต้องการคำนวณเกรดของนักเรียน 5 คนจากคะแนนของพวกเขา

How many student to calculate?: 5
1. Enter score: 86
Grade A
2. Enter score: 67
Grade C
3. Enter score: 34
Grade F
4. Enter score: 70
Grade B
5. Enter score: 100
Grade A

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

ในกรณีของเมธอดสำหรับคำนวณเกรด cal_grade คุณสามารถนำเมธอดของคุณไปให้คนอื่นใช้งาน โดยที่ไม่จำเป็นต้องรู้ว่าภายในเมธอดนั้นทำงานอย่างไร แต่เพียงแค่รู้ว่าเมธอดนี้ใช้งานอย่างไร นั่นก็คือรู้ว่าต้องส่งคะแนนเข้าไปและจะได้ผลลัพธ์เป็นเกรดกลับมาเท่านั้นเอง

puts Math.sqrt(2)    # => 1.4142135623730951

ยกตัวอย่างเช่นการใช้เมธอด sqrt จากโมดูล Math ซึ่งเป็นไลบรารี่มาตรฐานของภาษา Ruby เพื่อหารากที่สองของตัวเลข เราไม่จำเป็นต้องรู้ว่าเมธอดนี้ทำงานอย่างไร แต่เรารู้ว่าจะใช้งานมันอย่างไรก็เพียงพอแล้ว

กำหนดค่าเริ่มต้นให้กับอาร์กิวเมนต์

ในภาษา Ruby คุณสามารถกำหนดค่าเริ่มต้นให้กับอาร์กิวเมนต์ของเมธอดได้ โดยการใช้ตัวดำเนินการกำหนดค่า (=) หลังจากชื่อของอาร์กิวเมนต์และตามด้วยค่าที่ต้องการ นี่เป็นตัวอย่าง

def hello(name = "World")
    puts "Hello #{name}"
end

ในตัวอย่าง เราได้ทำให้อาร์กิวเมนต์ name มีค่าเริ่มต้นโดยการกำหนดค่าค่าเริ่มต้นให้กับอาร์กิวเมนต์เป็น "World" นั่นหมายความว่าเมื่อเราเรียกใช้งานเมธอด คุณสามารถที่จะไม่ส่งค่าสำหรับอาร์กิวเมนต์ได้ และค่าเริ่มต้นจะถูกนำมาใช้แทน

hello
hello("Mateo")

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Hello World
Hello Mateo

ในการเรียกเมธอด hello ครั้งแรก เราไม่ได้ส่งอาร์กิวเมนต์สำหรับอาร์กิวเมนต์ name เข้าไปยังเมธอด ดังนั้นตัวแปร name ใช้ "World" เป็นค่าของมัน ในการเรียกครั้งที่สอง เราส่งค่า "Mateo" เข้าไปยังเมธอด ดังนั้นค่านี้ถูกใช้เป็นค่าของตัวแปร name แทนค่าเริ่มต้น

อย่างไรก็ตาม สำหรับการกำหนดค่าเริ่มต้นให้กับอาร์กิวเมนต์นั้น อาร์กิวเมนต์ที่มีค่าเริ่มต้นต้องอยู่แบบติดกัน ยกตัวอย่างเช่น แบบชิดทางด้านซ้ายหรือชิดทางด้านขวา

# Correct
def method1(a = 1, b = 2, c)
    puts a, b, c
end

def method2(a, b = 2, c = 3)
    puts a, b, c
end

# Error
def method3(a = 1, b, c = 3)
    puts a, b, c
end

ในตัวอย่าง คุณสามารถกำหนดค่าเริ่มต้นให้กับเมธอดในแบบของเมธอด method1 และ method2 เนื่องจากว่าค่าเริ่มต้นของอาร์กิวเมนต์นั่นเริ่มจากทางด้านซ้ายและทางด้านขวา และอยู่ติดกัน และในตอนเรียกใช้งานเมธอด คุณต้องส่งค่าอาร์กิวเมนต์อย่างน้อยเท่ากับจำนวนของอาร์กิวเมนต์ที่ไม่มีค่าเริ่มต้น

อาเรย์อาร์กิวเมนต์

ในบางครั้ง คุณอาจจะต้องการส่งค่าเป็นจำนวนมากเข้ามายังเมธอด คุณสามารถกำหนดอาเรย์อาร์กิวเมนต์ให้กับเมธอดได้ อาเรย์อาร์กิวเมนต์สามารถใช้ร่วมกับอาร์กิวเมนต์ปกติได้แต่มันต้องอยู่หลังสุดเสมอ นี่เป็นรูปแบบการประกาศ

method_name(positional1,*arguments)

นี่เป็นตัวอย่างการใช้งานสำหรับอาเรย์อาร์กิวเมนต์

def method(*arguments)
    p arguments
end

method(1)
method(1, 2, 3)
method(true, false, 5, 1.23)
method("PHP", "Ruby", "Python", "Java")

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

[1]
[1, 2, 3]
[true, false, 5, 1.23]
["PHP", "Ruby", "Python", "Java"]

ในตัวอย่าง เมื่อเรากำหนดอาร์กิวเมนต์โดยการขึ้นต้นด้วยเครื่องหมายดอกจันทร์ (*) มันจะกลายมาเป็นอาเรย์อาร์กิวเมนต์ นั่นหมายความว่าคุณสามารถส่งอาร์กิวเมนต์มาจำนวนเท่าไหร่ก็ได้ในตอนเรียกใช้งานเมธอด โดยอาร์กิวเมนต์ทั้งหมดจะถูกรวบรวมเก็บไว้ในตัวแปรอาเรย์ arguments ที่เราสามารถนำไปใช้ต่อภายในเมธอดได้

ในตอนนี้ คุณอาจจะสามารถสังเกตได้แล้วว่าตัวอย่างของเมธอดที่เป็นอาเรย์อาร์กิวเมนต์ที่เราใช้กันอยู่ก็คือเมธอด puts นั่นเอง เราสามารถส่งอาร์กิวเมนต์เข้าไปยังเมธอดเท่าไหร่ก็ได้

puts 1
puts 2, 3, 4
puts "PHP", "Python", "Ruby", "Java"

Keyword อาร์กิวเมนต์

ในภาษา Ruby คุณสามารถกำหนด Keyword อาร์กิวเมนต์ให้กับเมธอดได้ โดยที่ Keyword อาร์กิวเมนต์นั้นจะต้องต่อท้ายอาร์กิวเมนต์แบบปกติเสมอ ดังรูปแบบต่อไปนี้

method_name(positional1, keyword1: value1, keyword2: value2)

นอกจากนี้ Keyword อาร์กิวเมนต์จะต้องมีค่าเริ่มต้นเสมอ มาดูตัวอย่าง

def introduce(name: "Mateo", lang: "Ruby")
    print name
    puts " is a #{lang} programer"
end

introduce()
introduce(lang: "Python")
introduce(name: "Danny")
introduce(lang: "Java", name: "John")

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Mateo is a Ruby programer
Mateo is a Python programer
Danny is a Ruby programer
John is a Java programer

ในตัวอย่าง เรามีเมธอดที่ชื่อว่า introduce ซึ่งเป็นเมธอดสำหรับแนะนำตัวโดยบอกชื่อและภาษาเขียนโปรแกรม ภายในเมธอดนั้นมี Keyword อาร์กิวเมนต์อยู่สองตัวคือ name และ lang และแต่ละอาร์กิวเมนต์นั้นจะมีค่าเริ่มต้นเสมอ และค่าเริ่มต้นเหล่านี้จะถูกใช้งานเมื่อคุณเรียกใช้งานเมธอดโดยที่ไม่ส่งค่าสำหรับอาร์กิวเมนต์เหล่านั้นมา

ในการส่งค่าอาร์กิวเมนต์สำหรับ Keyword อาร์กิวเมนต์นั้น จะเห็นว่าเราไม่จำเป็นต้องส่งตามลำดับที่อาร์กิวเมนต์ได้ถูกประกาศ

ตัวอย่างต่อมาเป็นการใช้งาน Keyword อาร์กิวเมนต์ร่วมกับอาร์กิวเมนต์แบบปกติ

def introduce(year, name: "Mateo", lang: "Ruby")
    print name
    print " is a #{lang} programer"
    puts " since #{year}"
end

introduce(2009)
introduce(1998, lang: "Java", name: "John")

ในกรณีนี้อาร์กิวเมนต์แบบปกติจะต้องถูกกำหนดก่อน Keyword อาร์กิวเมนต์ในตอนสร้างเมธอดเสมอ และเช่นเดียวกันกับในตอนเรียกใช้งานเมธอด ค่าของอาร์กิวเมนต์แบบปกติต้องถูกส่งไปก่อนเสมอ

เมธอดกับขอบเขตของตัวแปร

เมื่อเราสร้างเมธอดในภาษา Ruby เราสามารถเขียนคำสั่งต่างๆ ภายในเมธอดได้ตามที่ต้องการเหมือนกับนอกเมธอด แต่อย่างไรก็ตาม ทุกอย่างที่ถูกสร้างภายในเมธอด เช่น ตัวแปร จะสามารถใช้ได้เพียงในเมธอดนั้นเท่านั้น ยกตัวอย่างเช่น

def add(a, b)
    c = a + b
    return c
end

puts add(10, 20)

ในตัวอย่าง เมธอด add นั้นมีอาร์กิวเมนต์สองตัวคือ a และ b ซึ่งความจริงแล้ว อาร์กิวเมนต์เหล่านี้เป็นตัวแปรที่ถูกสร้างขึ้นอัตโนมัติเมื่อมีการเรียกใช้งานเมธอด และภายในเมธอดเราประกาศตัวแปร c สำหรับเก็บค่าผลรวม นั่นหมายความว่าภายในเมธอด add นั้นเรามีสามตัวแปร ซึ่งตัวแปรเหล่านี้สามารถใช้ได้ภายเพียงในเมธอดเท่านั้น และมันไม่มีอยู่ภายนอกเมธอด

มาดูตัวอย่างถัดไป เราจะเขียนเมธอดสำหรับแปลงอุณหภูมิจากองศาเซลเซียสไปยังองศาฟาเรนไฮต์และแปลงกลับในทำนองเดียวกัน

def celcius_to_faren(c)
    f = c * 9 / 5 + 32
    return f
end

def faren_to_celcius(f)
    c = (f - 32) * 5 / 9
    return c
end

f = celcius_to_faren(18)
c = faren_to_celcius(97)
puts "18 celcius is equal to #{f} fahrenheit"
puts "97 fahrenheit is equal to #{c} celcius"

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

18 celcius is equal to 64 fahrenheit
97 fahrenheit is equal to 36 celcius

ในตัวอย่าง เรามีเมธอดสำหรับแปลงอุณหภูมิจากองศาเซลเซียสไปยังองศาฟาเรนไฮต์ และเมธอดสำหรับแปลงอุณหภูมิจากองศาฟาเรนไฮต์ไปยังองศาเซลเซียส

สังเกตว่าในแต่ละเมธอดนั้นมีตัวแปร c และ f และใน main โปรแกรม (ส่วนหลักในการเขียนโปรแกรมที่ไม่ได้อยู่ภายในเมธอด) ของเราก็มีตัวแปร c และ f สำหรับเก็บค่าของอุณหภูมิเช่นเดียวกัน ซึ่งทั้งทั้งตัวแปร c และ f ที่อยู่ในเมธอดทั้งสองและภายนอกเมธอดนั้นอยู่คนละขอบเขตกัน นั่นหมายความว่ามันเป็นคนละตัวแปรกันนั่นเอง

เมธอดกับออบเจ็คในภาษา Ruby

Ruby นั้นเป็นภาษาเขียนโปรแกรมเชิงวัตถุอย่างสมบูรณ์ นั่นหมายความว่าทุกเมธอดในภาษา Ruby นั้นจะต้องเป็นเมธอดของออบเจ็คเสมอ โดยทั่วไปแล้วคำสั่งของโปรแกรม ตัวแปร เมธอด และทุกอย่างที่เราเขียนนั้นจะอยู่ภายในออบเจ็คที่ชื่อว่า main นี่เป็นตัวอย่าง

def add(a, b)
    a + b
end

puts self
puts self.class
puts add(1, 2)

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

main
3

ในตัวอย่าง เราได้ประกาศเมธอด add และเรียกใช้งานเมธอดดังกล่าว โดยทั่วไปแล้วโปรแกรมที่เราเขียนในภาษา Ruby จะทำงานอยู่ภายในออบเจ็ค main ซึ่งออบเจ็คนี้ถูกสร้างมาจากคลาส Object และเราได้มีการใช้งานตัวแปร self ซึ่งเป็นตัวแปรที่ใช้สำหรับอ้างถึงออบเจ็คในบริบทปัจจุบันที่โปรแกรมทำงานอยู่

ในตอนนี้ คุณอาจจะยังไม่เข้าใจเกี่ยวกับคลาสและออบเจ็คมากนัก ดังนั้นในตัวอย่างนี้ขอให้คุณเข้าใจเพียงแค่ว่าเมธอดที่เราสร้างนั้นอยู่ภายในคลาสเสมอ ซึ่งคุณจะได้เรียนเกี่ยวกับคลาสและออบเจ็คอีกครั้งในบทการเขียนโปรแกรมเชิงวัตถุในภาษา Ruby

เมธอดอาจจะอยู่ในคลาส (ซึ่งเป็นสิ่งที่ใช้สร้างออบเจ็ค) หรือภายในโมดูล ในภาษา Ruby เมธอดที่เราใช้ส่วนมากนั้นจะมาจากโมดูล ยกตัวอย่างเช่น เมธอด puts มาดูตัวอย่างการใช้งาน

puts "marcuscode"
Kernel.puts 2019

ในตัวอย่าง เราสามารถเรียกใช้งานเมธอด puts โดยไม่ต้องใส่ชื่อโมดูล Kernel นำหน้าชื่อของเมธอด นั่นเป็นเพราะว่าโมดูล Kernel เป็นโมดูลหลักและเป็นข้อยกเว้นที่การเรียกใช้งานเมธอด เราไม่จำเป็นต้องใส่ชื่อโมดูลในการเรียกใช้งานเมธอดก็ได้

puts Math.sin(1)
puts Math.cos(1)

อย่างไรก็ตาม สำหรับเมธอดในโมดูลอื่นๆ เช่น โมดูล Math เราจะต้องเรียกใช้งานเมธอดด้วยชื่อของโมดูลด้วยเสมอ

puts 1.even?
puts "marcuscode".reverse

และเนื่องจากทุกอย่างในภาษา Ruby นั้นเป็นออบเจ็ค ดังนั้นเราสามารถเรียกใช้งานเมธอดบนออบเจ็คชนิดต่างๆ ได้ ในตัวอย่างเมธอด even? ให้ตรวจสอบว่าตัวเลขนั้นเป็นจำนวนเต็มคู่หรือไม่ และเมธอด reverse เป็นการกลับค่าของ String ซึ่งแต่ละเมธอดที่คุณเห็นนั้นขึ้นอยู่กับประเภทของออบเจ็คด้วย ยกตัวอย่างเช่น เมธอด reverse นั้นสามารถใช้ได้เพียงออบเจ็คของ String

อย่างไรก็ตาม สำหรับเนื้อหาของเมธอดกับออบเจ็คนั้น คุณจะได้เรียนรู้อีกครั้งในบทคลาสและออบเจ็ค

เมธอดที่ลงท้ายด้วยเครื่องหมาย ! และ ?

ในภาษา Ruby นั้นมีชื่อของเมธอดที่ลงท้ายด้วยเครื่องหมายตกใจ (!) และลงท้ายด้วยเครื่องหมายคำุถาม (?) ซึ่งเครื่องหมายเหล่านี้นั้นเป็นเพียงส่วนหนึ่งของชื่อเมธอด แต่มันใช้สำหรับเตือนและบอกโปรแกรมเมอร์เกี่ยวกับการทำงานของเมธอดเพื่อให้พวกเขาใช้งานมันได้ง่ายขึ้น มาดูตัวอย่างว่ามันหมายความว่าอย่างไร

เราจะมาเริ่มต้นด้วยเมธอดที่ลงท้ายด้วยเครื่องหมายตกใจ (!)

a = "ruby"
b = "ruby"

c = a.upcase # return new string
b.upcase!

puts a      # => ruby 
puts b      # => RUBY

ในตัวอย่าง เราได้เรียกใช้เมธอด upcase และ upcase! ในสองออบเจ็คที่มีค่าเหมือนกัน เมธอดทั้งสองนั้นทำหน้าที่เหมือนกันคือแปลง String ให้เป็นตัวพิมพ์ใหญ่ แต่สิ่งที่แตกต่างกันคือเมธอด upcase! ซึ่งเป็นเมธอดที่ลงท้ายด้วยเครื่องหมาย ! จะนำผลลัพธ์ที่ได้อัพเดทค่าในออบเจ็ค b ในขณะที่เมธอด upcase ส่งค่าใหม่กลับมาแทน

นั่นหมายความเมื่อเราใช้งานเมธอดที่ลงท้ายด้วยเครื่องหมาย ! ค่าเดิมก่อนหน้าของเราจะหายไป เครื่องหมาย ! หลังชื่อเมธอดจึงเป็นสิ่งช่วยเตือนว่าเราจะสูญเสียข้อมูลก่อนหน้าเมื่อเรียกใช้งานเมธอดนี้ และในภาษา Ruby จึงเป็นธรรมเนียมว่าถ้าหากเมธอดมีการทำงานดังกล่าว ชื่อของมันควรจะลงท้ายด้วยเครื่องหมายตกใจ เพื่อเตือนให้โปรแกรมเมอร์ทราบก่อนที่จะใช้มัน มาดูอีกตัวอย่าง

a = "marcuscode"
puts a.reverse!     # => edocsucram
puts a.upcase!      # => EDOCSUCRAM

ในตัวอย่าง เป็นการเรียกใช้งานเมธอดที่ลงท้ายด้วยเครื่องหมาย ! ในการเรียกใช้งานครั้งแรก เมธอด reverse! นั้นได้ทำการกลับค่าของข้อความ และค่าที่ได้ถูกอัพเดทแทนที่ค่าเดิมในตัวแปร a หลังจากนั้นเราเรียกใช้งานเมธอด upcase! เพื่อแปลงข้อความเป็นตัวพิมพ์ใหญ่ ค่าที่เราได้จะเป็นค่าของข้อความที่กลับด้านไปแล้ว เพื่อแก้ปัญหานี้ เราจะเป็นต้องใช้เมธอดที่ไม่ลงท้ายด้วยเครื่องหมาย !

a = "marcuscode"
puts a.reverse     # => edocsucram
puts a.upcase      # => MARCUSCODE

เนื่องจากในการแปลงข้อความให้เป็นตัวพิมพ์ใหญ่ เราต้องการแปลงจากค่าเดิมในตอนที่ตัวแปรถูกประกาศ ดังนั้นในการเรียกใช้งานเมธอด reverse เนื้อหาในตัวแปร a จะยังคงไม่ถูกเปลี่ยนแปลง และเมื่อเราเรียกเมธอด upcase เราได้รับผลลัพธ์ตามที่คาดหวัง

เมธอดที่ไม่ท้ายด้วยเครื่องหมาย ! มีชื่อเรียกอีกอย่างหนึ่งว่าเมธอดอันตราย นั่นเป็นเหตุผลว่าทำไมมันมีเครื่องหมายดังกล่าวอยู่ท้ายชื่อ

โดยทั่วไปแล้ว Ruby มักมีเมธอดสองเวอร์ชันสำหรับการทำงานที่มีการเปลี่ยนแปลงเนื้อหาของออบเจ็ค นั่นคือเมธอดที่ลงท้ายด้วยเครื่องหมาย !และเมธอดที่ไม่ลงท้ายด้วยเครื่องหมาย ! โดยทั่วไปแล้วเมธอดแบบนี้มักพบอยู่ในคลาส String ไม่ใช่ทุกเมธอดที่ไม่เมธอดในเวอร์ชันของ !

a = "marcuscode"
a.upcase
a.upcase!
a.downcase
a.downcase!
a.capitalize
a.capitalize!
a.chomp
a.chomp!

ต่อมาเป็นตัวอย่างสำหรับการใช้งานเมธอดที่ลงท้ายด้วยเครื่องหมายคำถาม (?)

ในภาษา Ruby เมธอดที่ลงท้ายด้วยเครื่องหมายเป็นที่เข้าใจกันว่าเมธอดดังกล่าวส่งค่ากลับมาเป็น boolean เพื่อให้ง่ายต่อการสังเกตเมื่อนำไปใช้งานกับคำสั่งเลือกและควบคุมเงื่อนไข มาดูตัวอย่างการใช้งาน

year = 2019
puts year.even?
puts year.odd?
puts year.integer?

site = "marcuscode"
puts site.start_with?("mar")
puts site.end_with?("code")
puts site.ascii_only?

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

false
true
true
true
true
true

ในตัวอย่าง เป็นการใช้งานเมธอดต่างๆ บนออบเจ็คของตัวเลขและออบเจ็คของ String สังเกตว่าเมธอดทั้งหมดนั้นลงท้ายด้วยเครื่องหมายคำถาม นั่นเป็นเพราะว่าเมธอดเหล่านี้ส่งค่ากลับเป็น Boolean นั่นเอง

เมธอด even? ใช้เพื่อดูว่าตัวเลขนั้นเป็นจำนวนคู่หรือไม่ เมธอด odd? ใช้เพื่อดูว่าตัวเลขนั้นเป็นจำนวนคี่หรือไม่ และเมธอด integer? ใช้เพื่อดูว่าตัวเลขนั้นเป็นจำนวนเต็มหรือไม่ สำหรับเมธอดของ String เมธอด start_with? ใช้เพื่อดูว่าข้อความนั้นขึ้นต้นด้วยคำที่ต้องการหรือไม่ เมธอด end_with? ใช้เพื่อดูว่าข้อความนั้นลงท้ายด้วยคำที่ต้องการหรือไม่ และเมธอด ascii_only? ใช้เพื่อดูว่าตัวอักษรทั้งหมดในข้อความนั้นเป็น ASCII เท่านั้นหรือไม่

ดังนั้นเมื่อคุณสร้างเมธอด เมื่อเมธอดของคุณมีการเปลี่ยนแปลงข้อมูลภายในออบเจ็ค คุณใส่เครื่องหมาย ! ท้ายชื่อของเมธอดด้วย เพื่อบอกว่ามันเป็นเมธอดอันตราย และถ้าหากเมธอดของคุณส่งกลับค่าที่เป็น Boolean คุณก็ควรใส่เครื่องหมาย ? ท้ายชื่อเมธอด การทำเช่นนี้จะช่วยให้ชื่อเมธอดสือความหมายในสิ่งที่มันทำมากขึ้น และอย่างไรก็ตาม นี่เป็นไม่ใช้ข้อบังคับทีคุณต้องทำตาม แต่มันเป็นเพียงคำแนะนำ

ในบทนี้ คุณได้เรียนรู้เกี่ยวกับการสร้างและใช้งานเมธอดในภาษา Ruby และเราสามารถใช้ประโยชน์จากเมธอดในการสร้างฟังก์ชันเพื่อทำงานบางอย่างในโปรแกรม และที่สำคัญเราสามารถเรียกใช้งานเมธอดซ้ำๆ ได้ นั่นหมายความว่าเมื่อโค้ดของคุณทำงานบางอย่างที่เฉพาะเจาะจงคุณสามารถจัดระเบียบโค้ดเหล่านั้นด้วยสร้างเมธอดขึ้นมาได้

บทความนี้เป็นประโยชน์หรือไม่? Yes · No