ประเภทข้อมูลในภาษา Ruby

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

  • ประเภทข้อมูล
  • Boolean
  • Integer
  • Floating-point
  • Strings
  • Symbols
  • Rational
  • Complex
  • ประเภทข้อมูลอื่น

ประเภทข้อมูล คืออะไร

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

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

Boolean

Boolean เป็นประเภทข้อมูลที่มีค่าที่เป็นไปได้เพียงสองค่าคือ true และ false โดยมันใช้แสดงถึงค่าความจริงในทางตรรกศาสตร์ของคอมพิวเตอร์ ซึ่งค่า true นั้นใช้แสดงถึงค่าที่เป็นจริง ในขณะที่ false นั้นใช้แสดงถึงค่าที่เป็นเท็จ สำหรับการเขียนโปรแกรมคอมพิวเตอร์นั้น เรามักจะใช้ boolean สำหรับเก็บค่าบางอย่างที่มีเพียงสองค่าหรือสองสถานะ

boolean.rb
p true
p false

p 5 < 6
p 4 == 4
p 4 == 5

p true.class
p false.class

ในตัวอย่างนั้น เป็นการอธิบายข้อมูลประเภท boolean ซึ่งค่าของ boolean ที่เป็นไปได้นั้นจะมีเพียงสองค่าคือ true และ false เท่านั้น

p 5 < 6
p 4 == 4
p 4 == 5

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

p true.class
p false.class

ต่อมาเป็นการแสดงคลาสของข้อมูลประเภท boolean ซึ่งทั้งสองค่านั้นเป็นออบเจ็คจากคนละคลาสกัน ถึงแม้ว่ามันเป็นข้อมูลประเภทเดียวกันก็ตาม

true
false
true
true
false
TrueClass
FalseClass

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

ต่อไปมาดูตัวอย่างการใช้งาน boolean กับคำสั่งเงื่อนไขในภาษา Ruby ซึ่งเราได้พัฒนาเกมขึ้นใน และผู้เล่นต้องเข้าสู่ระบบก่อนเพื่อเล่นเกม

boolean2.rb
logged_in = true

if logged_in
    puts "Welcome to marcuscode"
else
    puts "Please log in or sign up"
end

ในตัวอย่าง เราได้ประกาศตัวแปร logged_in สำหรับเก็บค่าสถานะการเข้าสู่ระบบของผู้เล่นเป็น boolean

if logged_in

ในตัวอย่าง เป็นการใช้งานคำสั่งเลือกเงื่อนไข if ซึ่งโปรแกรมจะทำงานบล็อคของคำสั่ง if ถ้าหากค่าของตัวแปรเป็นจริง ไม่เช่นนั้นโปรแกรมจะทำงานในบล็อคคำสั่ง else แทน

Let's play the game

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

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

boolean3.rb
def greet(say_hi, name)
    if say_hi
        "Hi #{name}"
    else
        "Hello #{name}"
    end
end

puts greet(true, "Mateo")
puts greet(false, "Andy")
puts greet(true, "Iselin")

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

if say_hi

เราได้ใช้คำสั่งเลือกเงื่อนไข if เพื่อตรวจสอบค่าของ boolean เช่นเดิม ถ้าหากตัวแปร say_hi เป็นจริง โปรแกรมจะกล่าวคำทักทายด้วยคำว่า "Hi" ไม่เช่นนั้น โปรแกรมจะกล่าวคำทักทายด้วย "Hello" แทน

puts greet(true, "Mateo")
puts greet(false, "Andy")
puts greet(true, "Iselin")

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

Hi Mateo
Hello Andy
Hi Iselin

นี่เป็นผลลัพธ์การทำงานของโปรแกรม สังเกตว่าคำทักทายที่ได้นั้นจะขึ้นอยู่กับค่าของ boolean ที่เราส่งไปยังเมธอด

Integer

Integer นั้นเป็นข้อมูลประเภทจำนวนเต็มที่สามารถเขียนได้โดยไม่มีเศษส่วน ยกตัวอย่างเช่น 1, 13, 0 และ -2048 นั้นเป็นข้อมูลประเภทจำนวนเต็ม ในการเขียนโปรแกรม เรามักจะใช้จำนวนเต็มเพื่อเก็บข้อมูลที่สามารถนับได้ มาดูตัวอย่าง

integer.rb
puts 3
puts 17
puts 0
puts -2048

puts 3.class
puts 17.class
puts 0.class
puts -2048.class

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

3
17
0
-2048
Integer
Integer
Integer
Integer

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

ต่อไปมาดูตัวอย่างการใช้งานข้อมูลประเภท Integer ในการเขียนโปรแกรมกัน ซึ่งเป็นโปรแกรมแสดงผลจำนวนผลไม้ที่ Mateo มี

integer2.rb
apple = 3
orange = 10
total = apple + orange

puts "Mateo has #{apple} apples"
puts "Mateo has #{orange} oranges"
puts "Total fruits he has is #{total}"

ในตัวอย่าง เราได้ประกาศตัวแปรสองตัวเพื่อเก็บจำนวนของผลไม้แต่ละประเภท หลังจากนั้นนำตัวแปรทั้งสองมาบวกกันและเก็บค่าไว้ในตัวแปร total ซึ่งเมื่อตัวเลข integer สองตัวบวกกันจะได้ Integer ค่าใหม่ และสุดท้ายเราแสดงจำนวนผลไม้ทั้งหมดออกมา

Mateo has 3 apples
Mateo has 10 oranges
Total fruits he has is 13

นี่เป็นผลลัพธ์การทำงานของโปรแกรม ซึ่งเป็นการใช้งานตัวแปรสำหรับเก็บค่า Integer

โดยทั่วไปแล้วในภาษา Ruby นั้นใช้ระบบเลขฐานสิบในการแสดงผล ต่อไปเป็นตัวอย่างของการแสดงตัวเลข Integer ในเลขฐานต่างๆ ซึ่งภาษา Ruby นั้นได้สนับสนุนเลขฐานสิบ ฐานแปด ฐานสิบหก และฐานสอง

integer3.rb
dec = 34
oct = 042
hex = 0x22
bin = 0b100010

puts dec
puts oct
puts hex
puts bin

n = 34
puts sprintf("%d in decimal: %d", n, n)
puts sprintf("%d in octal: %o", n, n)
puts sprintf("%d in hexadecimal: %x", n, n)
puts sprintf("%d in binary: %b", n, n)

ในตัวอย่าง เราได้ประกาศตัวแปรสี่ตัวแปร และกำหนดค่าให้กับตัวแปรทั้งหมดด้วยการใช้เลขฐานสิบ ฐานแปด ฐานสิบหก และฐานสอง ค่าของตัวแปรทั้งหมดนั้นมีค่าเท่ากับ 34 ในเลขฐานสิบ

dec = 34
oct = 042
hex = 0x22
bin = 0b100010

ในการกำหนดค่าด้วยเลขฐานแปดนั้นจะขึ้นต้นด้วย 0 ในเลขฐานสิบหกจะต้องขึ้นต้นด้วย 0x และในเลขฐานสองจะต้องขึ้นต้นด้วย 0b และในเลขฐานแปดนั้นค่าที่มีได้คือ 0 - 7 ในเลขฐานสิบหกค่าที่มีได้คือ 0 - f และสุดท้ายเลขฐานสองค่าที่มีได้คือ 0 - 1

puts sprintf("%d in decimal: %d", n, n)
puts sprintf("%d in octal: %o", n, n)
puts sprintf("%d in hexadecimal: %x", n, n)
puts sprintf("%d in binary: %b", n, n)

คำสั่งต่อมาเป็นการใช้เมธอด sprintf เพื่อแสดงเลขตัวเลขในฐานต่างๆ ซึ่งเมธอดนี้จะส่งค่ากลับเป็นสตริงจากรูปแบบที่เรากำหนด โดยรูปแบบของการแสดงผลนั้นสามารถกำหนดในรูปแบบ %type ซึ่ง type นั้นเป็นตัวอักษรสำหรับประเภทข้อมูลชนิดต่างๆ ยกตัวอย่างเช่น %d นั้นเป็นจำนวนเต็มในฐานสิบ ในขณะที่ %b นั้นเป็นเลขฐานสอง

ตั้งแต่อาร์กิวเมนต์ที่สองเป็นต้นไปของเมธอด sprintf คุณจะต้องส่งค่าให้ครบกับ type ที่คุณระบบไว้ในอาร์กิวเมนต์แรกของเมธอด

sprintf("%type1 %type1 %type1", value1, value2, value3)

ในตัวอย่างนั้น %d นั้นเป็นจำนวนเต็มในเลขฐานสิบ %o จะแปลงเป็นเลขฐานแปด %x แปลงเป็นเลขฐานสิบหก และ %b แปลงเป็นเลขฐานสอง ซึ่งจากสี่รูปแบบการแสดงผลที่คุณเห็นนั้นเป็นเพียงส่วนหนึ่งของเมธอดนี้เท่านั้น

34
34
34
34
34 in decimal: 34
34 in octal: 42
34 in hexadecimal: 22
34 in binary: 100010

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

Floating-point number

Floating-point number เป็นประเภทข้อมูลของตัวเลขจำนวนจริง ซึ่งเป็นตัวเลขที่มีจุดทศนิยมเพื่อระบุความละเอียดของตัวเลขได้ ในภาษา Ruby นั้นเก็บค่าของ Float ในรูปแบบ Double-precision ซึ่งมีขนาดและความละเอียดเพียงพอสำหรับการเขียนโปรแกรมเพื่อใช้งานทั่วไป โดยทั่วไปแล้ว เราใช้ตัวเลขจำนวนจริงสำหรับเก็บข้อมูลที่ต้องการความละเอียด เช่น การคำนวณทางวิทยาศาสตร์

floating_number.rb
puts 1.25
puts 3.0
puts 1024.1234
puts -15.3

puts 1.25.class
puts 3.0.class
puts 1024.1234.class
puts -15.3.class

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

puts 1.25.class

ต่อมาเมธอด class ใช้เพื่อรับค่าคลาสของออบเจ็คตัวเลขของเรา ซึ่งตัวเลขทั้งหมดนั้นเป็นออบเจ็คของคลาส Float

1.25
3.0
1024.1234
-15.3
Float
Float
Float
Float

นี่เป็นผลลัพธ์การทำงานของโปรแกรม ในตอนแรกเราได้แสดงค่าของ Float ในขนาดต่างๆ และแสดงคลาสของออบเจ็คทั้งหมด

นอกจากการกำหนดค่า Float ด้วย Literal พื้นฐานแล้ว คุณยังสามารถใช้มันในรูปแบบสัญกรณ์วิทยาศาสตร์ได้ ซึ่งเป็นการลดรูปการแสดงผลของตัวเลขที่มีขนาดใหญ่มากหรือเล็กมากให้สั้นลง มาดูตัวอย่าง

floating_number2.rb
puts 1.3e4
puts 10e6
puts 5e-4
puts -83e-1

puts 8.0 / 2
puts 5.0 / 3
puts 8 / 2

ในตัวอย่าง เราเป็นการใช้งาน Float ในรูปแบบสัญกรณ์วิทยาศาสตร์ ซึ่งใช้ตัวอักษร e เพื่อแสดงถึงของเลขยกกำลังฐานสิบ ดังนั้น 1.3e4 จะหมายถึง 1.3 × 104 และมีค่าเท่ากับ 13000 ในขณะที่ 5e-4 จะหมายถึง 5 × 10-4 และมีค่าเท่ากับ 0.0005

puts 8.0 / 2

ต่อมาเป็นการหารตัวเลข ซึ่งการหารในภาษา Ruby นั้นเมื่อมีตัวเลขอย่างน้อยหนึ่งตัวเป็น Float (float / int) ผลลัพธ์ที่ได้จะเป็น Float เสมอ แต่ถ้าหากตัวเลขที่นำมาหารกันนั้นเป็น Integer ทั้งคู่ (int / int) ผลลัพธ์ที่ได้ก็จะเป็น Integer

13000.0
10000000.0
0.0005
-8.3
4.0
1.6666666666666667
4

และนี่เป็นผลลัพธ์การทำงานของโปรแกรม ซึ่งเป็นการใช้ตัวเลข Float ในรูปแบบสัญกรณ์วิทยาศาสตร์ และ Ruby จะเก็บมันในรูปแบบของจำนวนจริงจริงๆ และเราได้แสดงการหารตัวเลขกับข้อมูลประเภท Float

ต่อไปมาดูตัวอย่างการนำประเภทข้อมูล Float ไปประยุกต์ใช้ในการเขียนโปรแกรม เราจะเขียนโปรแกรมคำนวณเวลาในการเดินทางของรถยนต์

Mateo ได้ขับรถมาถึงถนนเข้าเมืองแห่งหนึ่ง และมันมีป้ายจำกัดความเร็วอยู่ที่ 40 กิโลเมตรต่อชั่วโมง ซึ่งเป็นความเร็วสูงสุดที่ Mateo สามารถขับได้ และถนนสายนี้ยาว 3.6 กิโลเมตร ซึ่งเป็นระยะทางทั้งหมดทีเขาต้องขับผ่าน จงหาว่าเขาจะใช้เวลาน้อยที่สุดเท่าไหร่ในการที่จะขับผ่านเมืองนี้ไปได้

floating_number3.rb
# Input data
speed_limit = 20
distance = 2.6

# Convert speed and distance to SI unit
v = speed_limit * 5 / 18 # meter per second
s = distance * 1000 # meter

# Caculate time
t = s / v

puts "Mateo will take #{t} seconds or"

# For readability
min = (t / 60).floor
sec = (t % 60).to_i
puts "#{min} minutes #{sec} seconds"

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

speed_limit = 20
distance = 2.6

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

v = speed_limit * 5 / 18
s = distance * 1000

เนื่องจากข้อมูลนำเข้าของเรานั้นไม่ใช้หน่วยของ SI unit (หน่วยที่ใช้ในการคำควณทางวิทยาศาสตร์) เราต้องแปลงกิโลเมตรต่อชั่วโมงให้เป็นเมตรต่อวินาที และแปลงกิโลเมตรให้เป็นเมตร ก่อนนำไปคำนวณหาเวลาที่มีหน่วยเป็นวินาทีด้วยคำสั่ง

t = s / v

ในคำสั่งนี้ เป็นการคำนวณหาเวลาทั้งหมดที่ต้องใช้ จากระยะทางและความเร็วที่ทราบ ซึ่งสูตรนี้เป็นสูตรความสัมพันธ์ระหว่างระยะทาง เวลา และความเร็ว ในวิชาฟิสิกส์ s = v * t และสุดท้ายเราจะได้เวลาทั้งหมดเป็นวินาที ซึ่งเป็นคำตอบที่เราต้องการหา

puts "Mateo will take #{t} seconds or"

min = (t / 60).floor
sec = (t % 60).to_i
puts "#{min} minutes #{sec} seconds"

เนื่องจากก่อนหน้าเราได้แสดงเวลาเป็นวินาที ซึ่งทำให้ยากต่อการทำความเข้าใจ เราจึงได้แสดงผลเป็นแบบนาที วินาทีแทน

Mateo will take 520.0 seconds or
8 minutes 40 seconds

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

Strings

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

string.rb
name = "Mateo"
site = 'marcuscode'

puts "#{name} visits #{site}" # => Mateo visits marcuscode

ในตัวอย่าง เราได้ประกาศตัวแปรสตริงสำหรับเก็บชื่อและชื่อเว็บไซต์ หลังจากนั้นแสดงผลมันออกมาทางหน้าจอ ในภาษา Ruby นั้นคุณสามารถสร้างสตริงได้สองวิธีคือ ด้วยเครื่องหมาย " (double quote) หรือ ' (single quote) ล้อมรอบข้อความที่ต้องการ ซึ่งทุกอย่างที่อยู่ระหว่างเครื่องหมายเหล่านี้จะเป็นเนื้อหาของสตริง

ต่อไปจะเป็นการอธิบายว่า การประกาศ String ในแต่ละแบบนั้นมีความแตกต่างกันอย่างไร

string2.rb
lang = "Ruby"
num_line = 15
sentent1 = "I love #{lang} language"
sentent2 = 'I love #{lang} language'
sentent3 = "I have written #{num_line} lines of #{lang} code"

puts sentent1
puts sentent2
puts sentent3

ในตัวอย่าง เราได้ประกาศตัวแปร sentent1 และ sentent2 ซึ่งใช้วิธีการสร้างคนละแบบ ความแตกต่างของสองทั้งสองแบบคือ double quote นั้นจะทำการแทนที่สตริง นั่นหมายความว่าเมื่อตัวแปรภาษาเจอกับ #{value} ภายในสตริง ค่าดังกล่าวจะถูกแทนที่ด้วยค่าของ value แทน ซึ่งวิธีการนี้เรียกว่าการแทนที่สตริง (String substitution)

ในขณะที่การใช้ single quote นั้นจะไม่มีการแทนที่สตริงเกิดขึ้น และคุณจะได้ค่าของสตริง เหมือนกับที่คุณกำหนดในตัวแปรแทน

I love Ruby language
I love #{lang} language
I have written 15 lines of Ruby code

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

ตัวอย่างต่อไป มาดูสิ่งที่น่าสนใจที่เราสามารถทำได้กับ String

string3.rb
str = "terminator"

puts str
puts str.size
puts str.class
puts

# Access specific index of string
puts str[0]
puts str[1]
puts str[-1]
puts str[2...4]
puts

# Calling method on string
puts str.upcase
puts str.capitalize
puts str.reverse
puts str.start_with?("ter")
puts

# String concatenation
puts "Hello " + "World!"
puts "One " + "two" + " three"

ในตัวอย่าง เราได้ประกาศตัวแปร String และแสดงข้อมูลเกี่ยวกับตัวแปรดังกล่าว เข้าถึงค่าของสตริงด้วย index เรียกใช้เมธอดของสตริง และการต่อสตริงเข้าด้วยกัน

puts str
puts str.size
puts str.class

ในส่วนแรก เราได้แสดงค่าของสตริงในตัวแปรออกมา เมธอด size ใช้เพื่อรับค่าขนาดของสตริงเป็นจำนวนตัวอักษร และเมธอด class ใช้เพื่อรับค่าคลาสของสตริงมาดู

puts str[0]
puts str[1]
puts str[-1]
puts str[2...4]

ต่อมาเป็นการเข้าถึงค่าของ String ด้วยตำแน่งของมันในรูปแบบ str[index] ซึ่งตำแหน่งแรกของสตริงจะเริ่มจาก 0 และตำแหน่งสุดท้ายคือ str.size - 1 คุณสามารถเข้าถึงค่าในสตริงจากตำแหน่งสุดท้ายได้ โดย -1 นั้นเป็นตำแหน่งที่นับจากท้ายของสตริง และ -2 เป็นตำแหน่งก่อนสุดท้ายตามลำดับ

puts str.upcase
puts str.capitalize
puts str.reverse
puts str.start_with?("ter")

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

puts "Hello " + "World!"
puts "One " + "two" + " three"
puts "One " + "two" + 3.to_s

สุดท้ายเป็นการต่อสตริงเข้าด้วยกันด้วยตัวดำเนินการ + ในการต่อสตริงด้วยวิธีนี้ ทุกค่าต้องเป็นสตริงเท่านั้น ซึ่งแตกต่างจากการแทนที่สตริงที่จะแปลงค่าให้เป็นสตริงให้อัตโนมัติ

terminator
10
String

t
e
r
rm

TERMINATOR
Terminator
rotanimret
true

Hello World!
One two 

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

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

Symbols

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

symbol.rb
s1 = :ruby
s2 = :python
s3 = :php

p s1 # => :ruby
p s2 # => :python
p s3 # => :php

p s1.class # => Symbol

ในตัวอย่าง เราได้สร้างตัวแปรสามตัวสำหรับเก็บค่าของ Symbol หลังจากนั้นแสดงค่าและคลาสของมันออกมาทางหน้าจอ

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

symbol2.rb
n1 = 3
n2 = 5
name = "Andy"

p local_variables # => [:n1, :n2, :name]
p local_variables.include? :n1 # => true
p local_variables.include? :n2 # => true
p local_variables.include? :color # => false

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

p local_variables.include? :n1

หลังจากนั้น เราใช้เมธอด include? ของอาเรย์เพื่อตรวจสอบว่าตัวแปร n1 ได้ถูกประกาศหรือไม่ โดยอาร์กิวเมนต์ที่ส่งเข้าไปในเมธอดจะเป็น Symbol ของตัวแปร

p Symbol.all_symbols

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

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

symbol3.rb
s1 = :on

def method1
    s2 = :on
    puts s2.object_id
end

class C1
    S3 = :on
end

puts s1.object_id
method1
puts C1::S3.object_id
puts :"on".object_id

เมื่อเราเข้าถึงและเรียกใช้ Symbol :on ในครั้งแรก Ruby จะสร้างออบเจ็คของ Symbol และเมื่อคุณเรียกใช้งาน Symbol :on มันจะใช้ออบเจ็คเดิมที่มีอยู่เสมอ ซึ่งนี่เองจะช่วยเพิ่มประสิทธิภาพและความเร็วในการทำงานของ Ruby

1102428
1102428
1102428
1102428

นี่เป็นผลลัพธ์การทำงานของโปรแกรม จะเห็นว่า Symbol :on ไม่ว่าจะสร้างมากี่ครั้งก็จะเป็นออบเจ็คเดียวกัน ซึ่งสามารถบอกได้โดยการดู Object id ของออบเจ็ค

นอกจาก Symbol จะถูกใช้ด้วย Ruby เองแล้ว คุณยังสามารถนำมันมาใช้ในการเขียนโปรแกรมได้ เรามักจะนำมันมาใช้แทนค่าคงทีและใช้เป็นคีย์ของ Hash

symbol4.rb
class Robot

    attr_reader :step_count

    def initialize()
        @step_count = 0
    end

    def move(direction, step)
        @step_count += step
        if (direction == :left)
            puts "Move to the left #{step} steps"
        elsif (direction == :right)
            puts "Move to the right #{step} steps"
        elsif (direction == :forward)
            puts "Move forward #{step} steps"
        elsif (direction == :backward)
            puts "Move backward #{step} steps"
        end
    end

end

r = Robot.new
r.move(:forward, 2)
r.move(:right, 4)
r.move(:left, 1)
r.move(:backward, 3)

puts "Total step moved: #{r.step_count}"

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

if (direction == :left)
    puts "Move to the left #{step} steps"

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

attr_reader :step_count

เมธอด attr_reader ใช้สำหรับสร้าง Getter เมธอดเพื่อทำให้ตัวแปรของออบเจ็คสามารถเข้าถึงได้จากภายนอกได้ จากในสั่งสุดท้ายของเรา r.step_count ซึ่งเมธอดนั้นจะรับ Symbol ของตัวแปรเป็นพารามิเตอร์

Move forward 2 steps
Move to the right 4 steps
Move to the left 1 steps
Move backward 3 steps
Total step moved: 10

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

if (direction == "left")
            puts "Move to the left #{step} steps"
...
r.move("left", 1)

ในการกลับกัน ถ้าหากคุณใช้ String ในการเปรียบเทียบ สิ่งที่ Ruby ทำคือจะสร้างออบเจ็ค String ใหม่ขึ้นมา และนำค่าของทั้งสองมาเปรียบเทียบกันซึ่งจะทำงานช้ากว่าการใช้ Symbol

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

อีกตัวอย่างหนึ่งสำหรับการใช้งาน Symbol คือเรามักจะใช้มันเป็นคีย์ของ Hash เนื่องจากว่ามันสามารถเข้าถึงข้อมูลได้เร็วกว่า

symbol5.rb
countries1 = {
    :th => "Thailand",
    :jp => "Japanse",
    :de => "German"
}

countries2 = {
    "th" => "Thailand",
    "jp" => "Japanse",
    "de" => "German"
}

puts countries1[:th]
puts countries2["th"]

ในตัวอย่าง เราได้ประกาศตัวแปร Hash countries1 และ countries2 ซึ่งในตัวแปรแรกนั้นใช้ Symbol เป็นคีย์ ส่วนตัวแปรที่สองใช้ String เป็นคีย์ และหลังจากนั้นเราแสดงผลค่า Hash จากคีย์ th ออกมาทางหน้าจอ

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

Rational number

Rational number นั้นเป็นตัวเลขที่สามารถเขียนได้ในรูปแบบเศษส่วน a / b ซึ่งทั้งสองตัวเลขนั้นเป็น Integer ซึ่ง a นั้นเป็นเศษและ b นั้นเป็นส่วนหรือผลหาร ส่วนค่าของ b นั้นจะไม่ต้องไม่เท่ากับ 0 ซึ่งในภาษา Ruby นั้นคุณสามารถสร้างตัวเลขแบบเศษส่วนด้วยเมธอด Kernel.Rational หรือเมธอด to_r หรือการต่อท้ายตัวเลขด้วยตัวอักษร r

นี่เป็นตัวอย่างของการสร้าง rational number ในภาษา Ruby

rational_number.rb
puts Rational(1)
puts Rational(2, 3)
puts Rational(4, -6)
puts 5.to_r
puts 3/5r

ในตัวอย่าง เป็นการสร้างตัวเลข rational ด้วยวิธีต่างๆ ในภาษา Ruby วิธีแรกนั้นเป็นการใช้เมธอด Rational จาก Kernel โมดูล วิธีที่สองเป็นการแปลงตัวเลขปกติให้เป็น rational ด้วยเมธอด to_r และสุดท้ายเป็นการกำหนดผ่าน Literal ซึ่งจะต้องลงท้ายตัวเลขด้วย r

1/1
2/3
-2/3
5/1
3/5

นี่เป็นผลลัพธ์การทำงานของโปรแกรม ซึ่งจะเป็นออบเจ็คที่มีค่าในรูปแบบ a/b เสมอ ออบเจ็ค rational ที่เราได้สร้างนั้น Ruby ยังแปลงให้เป็นเศษส่วนอย่างต่ำ และผลหารจะมากกว่า 0 เสมอ

Complex number

Complex number หรือจำนวนเชิงซ้อนนั้นเป็นตัวเลขที่สามารถเขียนได้ในรูปแบบ a + bi โดยที่ a และ b นั้นเป็นจำนวนจริง และ i นั้นเป็นคำตอบของสมการ x^2 = −1 ในภาษา Ruby นั้นคุณสามารถสร้างจำนวนเชิงซ้อนได้จากเมธอด Kernel.Complex เมธอด to_c หรือกำหนด Literal ที่ลงท้ายด้วย i นี่เป็นตัวอย่างของการใช้งานจำนวนเชิงซ้อน

complex_number.rb
puts 2+1i
puts Complex(1)
puts Complex(2, 3)
puts 3.to_c
puts 0.3.to_c

ในตัวอย่างนั้น คำสั่งแรกเป็นการสร้างจำนวนเชิงซ้อนด้วย Literal ของจำนวนเชิงซ้อนในรุปแบบ a+bi ต่อมาสร้างด้วยเมธอด Complex จาก Kernel โมดูล และสุดท้ายเป็นการใช้เมธอด to_c กับตัวเลขชนิดอื่นๆ เช่น Integer หรือ Float เป็นต้น

puts 2+1i
puts Complex(1)
puts Complex(2, 3)
puts 3.to_c
puts 0.3.to_c

นี่เป็นผลลัพธ์การทำงานของโปรแกรม เราได้แสดงผลจำนวนเชิงซ้อนจากการสร้างด้วยวิธีต่างๆ ในภาษา Ruby

ประเภทข้อมูลอื่นในภาษา Ruby

นอกจากประเภทข้อมูลทั้งหมดที่เราได้กล่าวไปข้างต้นแล้ว Ruby ยังมีประเภทข้อมูลอื่นๆ อีกที่คุณต้องเรียนรู้ เนื่องจากประเภทข้อมูลเหล่านี้มีโครงสร้างที่ซับซ้อนและไม่ได้สร้างมาจาก Literal ชนิดพื้นฐาน ดังนั้นเราได้แยกเนื้อหาออกไปในบทใหม่ ที่คุณจะได้เรียนรู้เกี่ยวกับประเภทข้อมูลเหล่านี้อย่างละเอียด:

  • Arrays
  • Hashes
  • Ranges
  • Regular Expressions
  • Procs

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

# Arrays
p [1, 2, 3, 4, 5]
p ["Mateo", "Andy", "Elizabeth"]

# Hash
h = { "th" => "Thailand", "jp" => "Japanse", "de" => "German" }
p h

# Ranges
p (1..10)
p (1...10)

# Regular Expression
p /pattern/
p /^marcuscode(\.com)?/

# Procs
double = Proc.new {|x| x * 2 }
p double.call(3)

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