Category Archives: Ruby

Ruby – Biểu thức

Biểu thức bao gồm toán tử và toán hạng. Toán tử là một kí tự đặc biệt thực hiện các phép tính toán trên các toán hạng và trả về một giá trị nào đó. Hầu hết các toán tử trong lập trình đều bắt nguồn từ toán học. Các toán tử khác nhau có các mức độ ưu tiên khác nhau. Toán hạng là các tham số đầu vào cho toán tử, trong lập trình thì toán hạng chính là các biến hoặc các giá trị.

Đây là bảng danh sách các toán tử của Ruby:

Tên Kí hiệu
Lấy thuộc tính, phương thức :: .
Thao tác mảng [ ] [ ]=
Lấy lũy thừa **
Toán tử phủ định, đảo bit, tăng, giảm ! ~ + -
Toán tử nhân, chia, chia lấy phần dư * / %
Toán tử cộng, trừ + -
Toán tử dịch bit << >>
Toán tử thao tác bit AND &
Toán tử thao tác bit OR ^ |
Toán tử so sánh hơn kém > >= < <=
Toán tử so sánh bằng <=> == === != =~ !~
Toán tử logic AND &&
Toán tử logic OR ||
Toán tử tạo phạm vi .. ...
Toán tử điều kiện ?:
Toán tử gán = += -= *= **= /= %= &= |= ^= <<= >>= ||= &&=
Phủ định not
Toán tử logic OR, AND or and

Các toán tử trong cùng một dòng có độ ưu tiên như nhau. Các toán tử ở các hàng trên có độ ưu tiên cao hơn các hàng dưới. Các toán tử có thể làm việc với một, hai hoặc ba toán hạng. Tùy vào từng trường hợp mà Ruby sẽ chọn toán tử nào để dùng vì có một số toán tử có kí hiệu giống nhau nhưng có ý nghĩa khác nhau.

Dấu của số

Chúng ta có 2 toán tử thay đổi dấu của số là +-. Ví dụ:

puts +2
puts -2

Dấu cộng chỉ định số đó là số nguyên dương, dấu trừ là số nguyên âm, nhưng cũng giống như trong toán hocj, dấu + có thể bỏ.

a = 1

puts a
puts -(a)
puts -(-(a))

Cũng giống như toán học, 2 dấu trừ sẽ chuyển thành dấu cộng.

1
-1
1

Toán tử gán

Toán tử gán sẽ gán giá trị cho biến, như chúng ta đã biết biến có nhiệm vụ lưu trữ giá trị. Toán hạng nằm phía bên phải sẽ được gán cho toán hạng nằm bên trái.

x = 1
puts x 

Chúng ta gán biến x có giá trị 1.

x = x + 1
puts x # prints 2

Trong lập trình toán hạng cũng có thể là một phép toán khác, trong ví dụ trên biến x được gán giá trị là x + 1.

1 = x; # Error

Chúng ta không thể gán một biến vào một giá trị, như thế là không hợp lệ, dòng code trên sẽ báo lỗi.

Toán tử lấy thuộc tính, phương thức

Đây là các toán tử có mức độ ưu tiên cao nhất, tức là trong một biểu thức thì chúng sẽ được thực hiện đầu tiên.

Toán tử :: có ý nghĩa là lấy hằng số, module hoặc một lớp được định nghĩa bên trong một lớp khác:

class MyMath
    Pi = 3.1415926535    
end

module People
    Name = "People"
end 

puts MyMath::Pi
puts People::Name

Trong đoạn code trên chúng ta có một lớp và một module, để lấy hằng số từ một lớp (hoặc module) thì chúng ta ghi tên lớp, sau đó là dấu :: rồi tên hằng, như thế các hằng số có tên giống nhau nhưng được đặt trong các lớp khác nhau sẽ không bị xung đột.

3.1415926535
People

Toán tử . truy xuất thuộc tính và phương thức của một đối tượng:

class Person
    
   def initialize name, age
       @name = name
       @age = age       
   end
   
   def info
       "#{@name} is #{@age} years old"
   end
    
end

p = Person.new "Jane", 17
puts p.info

Trong ví dụ trên chúng ta định nghĩa lớp Person có 2 phương thức do chúng ta định nghĩa. Chúng ta sử dụng toán tử . để truy xuất 2 phương thức này.

p = Person.new "Jane", 17
puts p.info

Chúng ta gọi phương thức new và phương thức info, phương thức new sẽ gọi đến phương thức initialize mà chúng ta đã viết, phương thức info sẽ trả về một chuỗi.

Jane is 17 years old

Toán tử toán học

Bao gồm các toán tử sau đây.

Kí hiệu Tên
+ Cộng
- Trừ
* Nhân
/ Chia
% Chia lấy phần dư
** Lũy thừa

Ví dụ:

a = 1
b = 2
c = 3

puts a + b + c
puts c - a
puts a * b
puts c / 3
puts c % a
puts c ** a

Các toán tử toán học giống y hệt như các phép toán trong toán học vậy.

puts c % a

Toán tử % chia hai số rồi lấy phần dư, ví dụ 9 chia 4 được 2 dư 1 thì toán tử này trả về 1.

6
2
2
1
0
3

Ví dụ 2:

puts 5 / 2

puts 5 / 2.0
puts 5.0 / 2
puts 5.to_f / 2

Trong ví dụ này chúng ta thực hiện phép chia trên số nguyên và số thực.

puts 5 / 2

Khi chúng ta thực hiện phép chia 2 số nguyên thì kết quả trả về là số nguyên.

puts 5 / 2.0
puts 5.0 / 2
puts 5.to_f / 2

Nếu một trong 2 toán hạng là số thực thì kết quả trả về là một số thực, ngoài ra chúng ta có thể dùng phương thức to_f để chuyển một số nguyên thành một số thực.

2
2.5
2.5
2.5

Ví dụ 3:

puts 5.div 2.0
puts 5.fdiv 2
puts 5.quo 2
puts 5.0.quo 2.0

Ngoài toán tử / thì chúng ta còn có các phương thức div, fdivquo cũng thực hiện phép chia.

puts 5.div 2.0

Phương thức div thực hiện phép chia số nguyên và trả về số nguyên cho dù toán hạng có là số thực.

puts 5.fdiv 2

Phương thức fdiv thì lại trả về số thực mặc dù toán hạng có là số nguyên.

puts 5.quo 2
puts 5.0.quo 2.0

Phương thức quo sẽ thực hiện phép chia và trả về số hữu tỉ dưới dạng phân số nếu các toán hạng là số nguyên, nếu một trong hai toán hạng là số thực thì trả về số thực.

2
2.5
5/2
2.5

Toán tử logic

Ruby có các toán tử logic sau:

Kí hiệu Tên
&& AND
|| OR
! negation

Toán tử logic sẽ trả kết quả về là một đối tượng boolean, tức là chỉ có true hoặc false. Ngoài 3 toán tử &&, ||! thì còn có 3 toán tử có tác dụng tương tự nhưng độ ưu tiên thấp hơn là and, ornot.

Ngoài ra các toán tử so sánh hay quan hệ cũng trả về một giá trị boolean:

x = 1
y = 2

puts x == y
puts y > x

if y > x then
    puts "y is greater than x"
end

Trong đoạn code trên chúng ta sử dụng toán tử so sánh == và toán tử quan hệ >.

puts x == y
puts y > x

Cả 2 dòng trên sẽ trả về kết quả là một giá trị boolean.

if y > x then
    puts "y is greater than x"
end

Các toán tử quan hệ thường được dùng trong câu lệnh điều kiện if, trong đoạn code trên phương thức puts sẽ được thực thi nếu biểu thức trong if trả về true.

Ví dụ 1:

puts true && true
puts true && false
puts false && true
puts false && false

Toán tử && trả về true nếu cả 2 toán hạng đều có giá trị là true.

true
false
false
false

Ví dụ 2:

puts true || true
puts true || false
puts false || true
puts false || false

Toán tử || trả về true nếu một trong 2 toán hạng là true, ngược lại trả về false.

true
true
true
false

Ví dụ 3:

puts !0
puts !1
puts !true
puts !false

puts ! (4<3)
puts ! "Ruby".include?("a")

Toán tử ! sẽ đảo ngược giá trị true thành false và ngược lại.

false
false
false
true
true
true

Khi Ruby thực hiện toán tử ||&& thì các toán hạng sẽ lần lượt được đánh giá, nếu toán hạng đầu tiên đủ điều kiện để đưa ra kết quả thì dừng lại chứ không xem xét tới các toán hạng phía sau nữa. Ví dụ trong biểu thức true || false thì Ruby chỉ cần nhìn thấy toán hạng đầu tiên là true thì sẽ trả về true luôn chứ không xem xét toán hạng thứ hai là true hay false.

Toán tử so sánh

Đây là các toán tử so sánh lớn hơn, bé hơn:

Kí hiệu tên
< bé hơn
<= bé hơn hoặc bằng
> lớn hơn
>= lớn hơn hoặc bằng

Ví dụ:

p 1 < 2 p 2 > 3
p 3 >= 3

Trong đoạn code trên, phép toán 1 < 2 trả về true, phép toán 2 > 3 trả về false. Phép toán 3 >= 3 trả về true.

Toán tử thao tác bit

Con người chúng ta thường làm việc với hệ cơ số 10 vì mặc nhiên chúng ta có 10 ngón tay, 10 ngón chân nên rất dễ tính toán, máy tính thì lại không như vậy, máy tính chỉ hiểu được hệ cơ số 2 – tức hệ nhị phân. Bạn cần nắm rõ cách hoạt động của các phép toán thao tác trên bit trước khi đi vào tìm hiểu thêm vì ở đây mình sẽ chỉ giải thích sơ lược qua các ví dụ.

Trong Ruby có các toán tử thao tác bit sau:

Kí hiệu ý nghĩa
~ Đảo ngược bit
^ Phép XOR
& Phép AND
| Phép OR
<< Dịch trái 1 bit
>> Dịch phải 1 bit

Thường thì chúng ta cũng ít khi dùng các toán tử này.

Ví dụ:

puts ~ 7   # prints -8 
puts ~ -8  # prints 7

puts 6 & 3  # prints 2
puts 3 & 6  # prints 2

puts 6 ^ 3  # prints 5
puts 3 ^ 6  # prints 5

puts 6 | 3  # prints 7
puts 3 | 6  # prints 7

puts 6 << 1  # prints 12
puts 1 << 6 # prints 64 puts 6 >> 1  # prints 3
puts 1 >> 6  # prints 0

Phép đảo ngược bit ~ sẽ chuyển tất cả các bit từ 0 sang 1 và ngược lại. Trong ví dụ này, 7 trong hệ 10 là 0111 trong hệ 2,  đảo ngược lại sẽ là 1000, mặc định Ruby làm việc với số nguyên có dấu, mà bit đầu tiên là bit xác định có dấu hay không nên 1000 trong hệ 2 sẽ là -8 trong hệ 10.

puts ~ 7   # prints -8 
puts ~ -8  # prints 7

Toán tử & sẽ thực hiện phép AND 2 số, trong đó nếu có cả 2 bit đều là 1 thì kết quả là 1, ngược lại là 0. Trong ví dụ này 6 & 30110 & 0011 = 0010, tức là số 2 trong hệ 10.

puts 6 & 3  # prints 2
puts 3 & 6  # prints 2

Toán tử ^ thực hiện phép XOR, nếu 2 bit giống nhau thì kết quả là 0, khác nhau thì là 1. Trong ví dụ này 6 ^ 3 tương đương 0110 ^ 0011 = 0101 là 5 trong hệ 10.

puts 6 ^ 3  # prints 5
puts 3 ^ 6  # prints 5

Toán tử | thực hiện phép OR, nếu một trong 2 bit là 1 thì kết quả là 1, ngược lại nếu cả 2 bit là 0 thì kết quả là 0. Ở đây 6 | 3 tương đương 0110 | 0011 = 0111 là 7 trong hệ 10.

puts 6 | 3  # prints 7
puts 3 | 6  # prints 7

Toán tử << dịch 1 bit sang trái, toán tử >> dịch 1 bit sang phải, ví dụ 6 << 1 tức là dịch 0110 sang 1 bit, thành 1100 tức 12 trong hệ 10, nếu tiếp tục dịch 12 << 1 thì được 11000 tức là 24 trong hệ 10. Nghĩa là phép dịch bit trái sẽ nhân số đó lên 2 lần. Tương tự phép dịch bit phải chia số đó cho 2.

puts 6 << 1  # 12
puts 1 << 6 # 64 puts 6 >> 1  # 3
puts 1 >> 6  # 0

Toán tử hợp

Toán tử hợp ở đây nghĩa là gộp các toán tử với toán tử gán = để thực hiện tính toán và gán giá trị luôn.

Ví dụ:

a = 0

a = a + 1
a += 1
puts a


b = 0

b = b - 8
b -= 8
puts b

Toán tử += có nghĩa là cộng rồi gán, chẳng hạn a += 1 tức là a + 1 rồi gán vào biến a, phép toán này tương đương với a = a + 1.

Đây là các toán tử hợp có trong Ruby:

-=   *=  **=  /=   %=   &=   |=   <<= >>= 

Mức độ ưu tiên của các toán tử

Mức độ ưu tiên toán tử cho biết trong một biểu thức thì toán tử nào sẽ được thực hiện trước.

3 + 5 * 5  # Result: 28

Ví dụ như trong biểu thức gồm có phép nhân và phép cộng thì phép nhân được thực hiện trước và phép cộng được thực hiện sau.

(3 + 5) * 5  # Result: 40

Để tăng độ ưu tiên thì chúng ta bọc biểu thức trong cặp dấu ngoặc tròn ()Các biểu thức trong cặp dấu ngoặc tròn sẽ được thực thi trước.

9 / 3 * 3   # Result: 9

Các toán tử có độ ưu tiên bằng nhau sẽ được thực hiện từ trái sang phải, giống hoàn toàn với toán học.

Toán tử phạm vi

Ruby có 2 toán tử phạm vi, dùng để tạo các đối tượng thuộc dạng danh sách trong một phạm vi nào đó, thường là phạm vi số hoặc kí tự.

p (1..3).to_a
p (1...3).to_a

p ('a' .. 'l').to_a

Toán tử i..j tạo danh sách các phần tử từ i tới j, bao gồm cả j, toán tử i...j tạo danh sách các phần tử từ i tới j nhưng không bao gồm j, tức là từ i tới j-1.

p ('a' .. 'l').to_a

Chúng ta có thể đưa vào dãy số hoặc dãy kí tự. Phương thức to_a sẽ chuyển danh sách này về kiểu mảng.

[1, 2, 3]
[1, 2]
["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"]

Toán tử điều kiện

Toán tử này trả về một trong 2 biểu thức tùy thuộc vào giá trị biểu thức điều kiện mà chúng ta đề ra. Cú pháp:

biểu thức điều kiện ? biểu thức 1 : biểu thức 2

Có pháp trên có nghĩa là nếu biểu thức điều kiệntrue thì thực hiện biểu thức 1, nếu false thì thực hiện biểu thức 2. Ví dụ:

age = 32

adult = age >= 18 ? true : false

if adult then
    puts "Adult"
else
    puts "Not adult"
end

Trong ví dụ trên chúng ta in ra các string khác nhau tùy vào giá trị của biến adult.

adult = age >= 18 ? true : false

Biến adult sẽ có giá trị là true nếu biến age lớn hơn 18, ngược lại adultfalse.

Adult

Ruby – String

Trong phần này chúng ta sẽ tìm hiểu kỹ hơn về kiểu dữ liệu String.

String là một chuỗi các kí tự được bọc trong cặp dấu nháy đơn hoặc nháy kép.

puts 'Python'
puts "Ruby"

Trong ví dụ trên chúng ta sử dụng cả 2 loại dấu nháy để tạo string.

Python
Ruby

Nếu bạn muốn in ra cả ký tự dấu nháy thì có 2 cách:

puts "There are many stars" 
puts "He said, \"Which one is your favourite?\""

puts 'There are many stars'
puts 'He said, "Which one is your favourite?"'

Cách thứ nhất là đặt trước dấu nháy ký tự \ và Ruby sẽ in ra dấu nháy đó. Cách thứ 2 là trộn dấu nháy đơn với dấu nháy kép, chẳng hạn như chúng ta bọc string bằng cặp dấu nháy đơn và bên trong chúng ta cho in ra dấu nháy kép.

There are many stars.
He said, "Which one is your favourite?"

Ký tự thoát

Ký tự thoát là các ký tự đặc biệt dùng để điều khiển string chứ không được in ra màn hình.

puts "one\ntwo\nthree\nfour"
puts "bbb\raaa" 
puts "Joan\b\b\bane" 
puts "Towering\tinferno" 

Kí tự \n có nghĩa là xuống dòng, bất kì kí tự nào nằm sau \n đều được xuống dòng. Kí tự \r đưa dấu nháy trên màn hình về vị trí đầu dòng.  Kí tự \t cách một đoạn dài bằng một dấu tab giống như khi chúng ta gõ nút tab, kí tự \b xóa một kí tự đứng trước nó.

one
two
three
four
aabbb
Jane
Towering      inferno

Nếu muốn in ra cả ký tự \ thì chúng ta đưa vào là \\.

puts "Escape character \\"
Escape character \

Lấy từng phần tử của string

Chúng ta có thể lấy từng phần tử của string.

msg = "Ruby language"

puts msg["Ruby"]
puts msg["Python"]

puts msg[0]
puts msg[-1]

puts msg[0, 3]
puts msg[0..9]
puts msg[0, msg.length]

Để có thể lấy các phần tử của string thì chúng ta sử dụng cặp dấu ngoặc vuông [] vừa đưa vào bên trong đó chỉ số, khoảng hoặc một string khác.

puts msg["Ruby"]

Khi đưa vào một string bên trong cặp dấu [] thì Ruby sẽ tìm chuỗi đó trong chuỗi gốc, nếu tìm thấy thì in ra chuỗi, nếu không thì in ra chuỗi rỗng.

puts msg[0]

Nếu đưa vào một con số nào thì chúng ta được kí tự tại vị trí đó, chuỗi trong Ruby được đánh số từ 0.

puts msg[-1]

Ruby cũng hỗ trợ chỉ số âm, đưa vào số âm thì sẽ được kí tự từ cuối string.

puts msg[0, 3]

Khi đưa vào 2 chữ số cách nhau bởi dấu phẩy, ví dụ [i, n] thì chúng ta lấy được n kí tự từ vị trí i.

puts msg[0..9]

Chúng ta cũng có thể đưa vào một khoảng giá trị, [0..9] sẽ lấy về chuỗi kí tự từ vị trí 0 đến vị trí 9.

puts msg[0, msg.length]

Phương thức length trả về độ lớn của chuỗi nên dòng trên có nghĩa là lấy toàn bộ chuỗi.

Ruby

R
e
Rub
Ruby langu
Ruby language

Truyền biến vào string

Chúng ta có thể truyền giá trị của các biến khác vào string để hiển thị, biến được truyền vào có dạng #{<tên biến>}. Ví dụ:

#!/usr/bin/ruby

name = "Jane"
age = 17

puts "#{name} is #{age} years old"

Giá trị của biến nameage sẽ được hiển thị tương ứng.

Jane is 17 years old

Chúng ta cũng có thể thực hiện các biểu thức với các biến được truyền vào:

x = 5
y = 6

puts "#{x} x #{y} = #{x*y}"
5 x 6 = 30

Nối chuỗi

Nối chuỗi tức là tạo một chuỗi từ các chuỗi con.

lang = "Ruby" + " programming" + " languge"
puts lang

lang = "Python" " programming" " language"
puts lang

lang = "Perl" << " programming" << " language"
puts lang

lang = "Java".concat(" programming").concat(" language")
puts lang

Có rất nhiều cách để nối một chuỗi. Để nối một chuỗi thì chúng ta có thể dùng toán tử cộng +, viết 2 chuỗi đứng liền nhau, dùng toán tử <<,  hoặc dùng phương thức concat().

Ruby programming languge
Python programming language
Perl programming language
Java programming language

So sánh chuỗi

Ruby hỗ trợ một số toán tử và phương thức giúp so sánh chuỗi một cách dễ dàng.

puts "12" == "12"
puts "aa" == "ab"
puts "Ruby".eql? "Jan"

Chúng ta có thể so sánh chuỗi bằng toán tử == hoặc phương thức eql?. Kết quả trả về True nếu 2 chuỗi giống nhau và ngược lại.

true
false
false

Ngoài ra Ruby còn có toán tử <==> dùng để so sánh chuỗi, toán tử này không trả về True hay False mà trả về 1, 0, -1:

  • 1: chuỗi bên trái lớn hơn chuỗi bên phải
  • -1: chuỗi bên trái bé hơn chuỗi bên phải
  • 0: hai chuỗi bằng nhau

Chuỗi a được gọi là bé hơn chuỗi b nếu kí tự tương ứng của chuỗi a có thứ tự cao hơn kí tự tương ứng bên chuỗi b trong bảng mã ASCII. Ví dụ, khi so sánh "a" <==> "b" thì kí tự a nằm trước kí tự b trong bảng mã ASCII nên a sẽ lớn hơn b. Nếu 2 kí tự bằng nhau thì Ruby sẽ tiếp tục so sánh kí tự tiếp theo của 2 chuỗi cho đến hết.

puts "a" <==> "b"
puts "b" <==> "a"
puts "a" <==> "a"
-1
1
0

Các phương thức trong String

String cũng là một đối tượng trong Ruby do đó các đối tượng string có các phương thức hữu ích mà chúng ta có thể sử dụng.

Ví dụ 1:

word = "Methods"

puts "Size of #{word}: #{word.size}"

puts word.include? "tho"
puts word.include? "od"

puts

puts word.empty?
word.clear
puts word.empty?

Trong đoạn code trên chúng ta sử dụng 4 phương thức của đối tượng string.

puts "Size of #{word}: #{word.size}"

Phương thức size lấy số lượng kí tự có trong string.

puts word.include? "tho"

Đoạn code trên dùng phương thức include?, phương thức này cho biết chuỗi “tho” có nằm trong chuỗi “Methods” hay không.

puts word.empty?
word.clear

Phương thức empty? cho biết string có rỗng hay không, phương thức clear sẽ xóa toàn bộ string.

Size of Methods: 7
true
true

false
true

Ví dụ 2:

ruby = "Ruby"

puts ruby.upcase
puts ruby.downcase
puts ruby.capitalize
puts ruby.swapcase

Ruby có 4 phương thức để chuyển kí tự qua lại giữa chữ hoa với chữ thường. Phương thức upcase chuyển toàn bộ string thành in hoa. Phương thức downcase là chuyển thành chữ in thường. Phương thức capitalize viết hoa chữ cái đầu trong string, còn lại viết thường. Phương thức swapcase chuyển kí tự hoa thành thường và ngược lại.

RUBY
ruby
Ruby
rUBY

Ví dụ 3:

str1 = "ruby.com"
str2 = "python.com"

puts str1.start_with? "ruby"
puts str2.start_with? "ruby."

puts str1.end_with? ".com"
puts str2.end_with? ".com"

Trong ví dụ trên, phương thức start_with? cho biết chuỗi str1str2 có bắt đầu bằng chuỗi “ruby” hay không. Ngược lại, phương thức end_with? cho biết chuỗi có kết thúc bằng chuỗi “.com” hay không.

true
false
true
true

Ví dụ 4:

msg = "Ruby\nPython"

puts msg
puts msg.inspect

Phương thức inspect sẽ in các ký tự thoát ra luôn chứ không dùng để điều khiển chuỗi nữa.

Ruby
Python
"Ruby\nPython"

Định dạng chuỗi

Định dạng chuỗi là hiển thị chuỗi theo nhiều cách khác nhau bằng cách chèn các chuỗi đặc tả. Chuỗi đặc tả có kí tự bắt đầu là kí tự % được đặt bên trong cặp dấu nháy đơn hoặc nháy kép cùng với chuỗi gốc.

Chuỗi đặc tả có dạng sau đây:

%[cờ][độ lớn][độ chính xác]<tên đặc tả>

Trong đó cờ, độ lớnđộ chính xác là các tham số tùy chọn, không có cũng được. Tên đặc tả là kiểu hiển thị của dữ liệu. Chúng ta sẽ xem các ví dụ dưới đây.

Ví dụ 1:

puts "There are %d oranges in the basket." % 12
puts "There are %d oranges and %d apples in the basket." % [12, 10]
puts "Speed: %f km/h" % 62.1
puts "Name: %s" % "iPhone 5"

Khi chúng ta đặt %d bên trong chuỗi thì khi dịch Ruby sẽ hiểu là phải đưa một số nguyên vào vị trí đó thay thế cho chuỗi %d. Các tham số sẽ được đưa vào sau dấu % phía sau chuỗi. Ngoài ra chúng ta cũng có thể đưa vào nhiều tham số bằng cách đặt chúng trong cặp dấu [] và ngăn cách nhau bởi dấu phẩy.

Đặc tả %d hiển thị số nguyên, %f là số chấm động, %s là hiển thị một chuỗi.

There are 12 oranges in the basket.
There are 12 oranges and 10 apples in the basket.
Speed: 62.100000 km/h
Name: iPhone 5

Ví dụ 2:

puts "%d" % 300
puts "%x" % 300
puts "%o" % 300
puts "%b" % 300
puts "%e" % (5/3.0)

Kiểu số nguyên có thể được hiển thị trên nhiều hệ cơ số khác nhau. Chẳng hạn %d là hệ 10, %x là hệ 16, %o là hệ 8, %b là hệ nhị phân (hệ 2), %e là hiển thị theo kiểu số mũ.

300
12c
454
100101100
1.666667e+00

Tham số độ chính xác là một con số đứng giữa kí tự % và kí tự đặc tả, tham số này có nhiều ý nghĩa khác nhau với từng kiểu dữ liệu khác nhau.

Đối với số nguyên thì độ chính xác là số lượng chữ số được hiển thị, nếu giá trị không đủ thì Ruby sẽ tự động chèn thêm các chữ số 0 vào trước, mặc định thì tham số này là 1 tức là không chèn thêm vào.

Đối với số thực thì là số lượng chữ số được hiển thị nằm sau phần thập phân.

Đối với kiểu chuỗi thì độ chính xác có nghĩa là số lượng kí tự cần được hiển thị.

Ví dụ 3:

puts 'Height: %f %s' % [177.3, 'cm']
puts 'Height: %.1f %s' % [177.3, 'cm']

puts "%d" % 16
puts "%.5d" % 16

puts "%s" % "Ruby"
puts "%.5s" % "Python"

Trong ví dụ trên, %.1f tức là hiển thị 1 chữ số sau phần thập phân. Mặc định Ruby hiển thị 6 chữ số sau phần thập phân nên nếu không đủ thì Ruby sẽ tự động chèn thêm các số 0 vào trước.

Tương tự, mặc định Ruby hiển thị độ chính xác là 1 với số nguyên, nhưng nếu chúng ta thiết lập là %.5d thì Ruby sẽ tự chèn thêm các số 0 vào trước cho đủ 5 chữ số.

%.5s cũng giống 2 kiểu trên ở chỗ là sẽ chỉ cho phép hiển thị 5 chữ cái, nếu số lượng chữ cái quá nhiều thì các chữ cái sau cùng sẽ bị lược bỏ, nhưng nếu không đủ số lượng thì Ruby cũng chẳng chèn thêm kí tự nào vào.

Height: 177.300000 cm
Height: 177.3 cm
16
00016
Ruby
Pytho

Ví dụ 4: Tham số độ lớn quy định số lượng kí tự tối thiểu cần được hiển thị ra.

puts "%d" % 1
puts "%d" % 12
puts "%d" % 123
puts "%d" % 1234
puts "%d" % 12345

puts "%10d" % 1
puts "%10d" % 12
puts "%10d" % 123
puts "%10d" % 1234
puts "%10d" % 12345

Tham số độ lớn nằm trước dấu chấm trong chuỗi đặc tả. Nếu dữ liệu không đủ số lượng kí tự thì Ruby sẽ tự động chèn thêm các khoảng trống vào phía trước chuỗi, ngoài ra chúng ta cũng có thể ghi số âm và Ruby sẽ đưa các kí tự khoảng trống vào phía sau chuỗi.

1
12
123
1234
12345
         1
        12
       123
      1234
     12345

Tham số cờ quy định một số kiểu hiển thị khác mà chúng ta sẽ xem sau đây.

Ví dụ 5:

puts "%010d" % 1
puts "%010d" % 12
puts "%010d" % 123
puts "%010d" % 1234
puts "%010d" % 12345

puts "%-10d" % 1
puts "%-10d" % 12
puts "%-10d" % 123
puts "%-10d" % 1234
puts "%-10d" % 12345

Cờ 0 sẽ chèn thêm một số lượng số 0 vào trước số thay vì chèn khoảng trống. Cờ dấu trừ “-” sẽ canh lề trái các chữ số.

0000000001
0000000012
0000000123
0000001234
0000012345
1 
12 
123 
1234 
12345

Ngoài ra còn có các cờ khác như dấu *, +, #, b, d, u, x…. bạn có thể tìm hiểu thêm tại đây.

Ruby – Kiểu dữ liệu – Phần 2

Trong phần này chúng ta tiếp tục tìm hiểu về các kiểu dữ liệu của Ruby.

Số hữu tỉ – Rational

Số hữu tỉ là số có thể biểu diễn dưới dạng phân số. Sử dụng số hữu tỉ sẽ giúp tránh các lỗi về làm tròn số vì chúng ta có thể biểu diễn chúng dưới dạng phân số. Ruby có lớp Rational hỗ trợ làm việc với số hữu tỉ. Một số đối tượng trong Ruby có phương thức to_r để chuyển một số thành số hữu tỉ.

puts 5.to_r
puts "43".to_r
puts 1.5.to_r

p Rational 0
p Rational 2/5.0
p Rational 1.5

Trong đoạn code trên chúng ta thực hiện một số thao tác với số hữu tỉ.

puts 5.to_r

Chúng ta có thể chuyển số nguyên 5 sang 5/1 bằng phương thức to_r.

p Rational 1.5

Hoặc chúng ta có thể tạo ra từ lớp Rational.

5/1
43/1
3/2
(0/1)
(3602879701896397/9007199254740992)
(3/2)

Đối tượng nil

Trong C++, Java… có đối tượng NULL thì trong Ruby chúng được gọi là nil. Đây là một đối tượng mô tả giá trị “không có”, ý nói một biến không có giá trị gì cả. nil là một đối tượng tĩnh, tức là trong Ruby chỉ có một đối tượng nil duy nhất giống như đối tượng true hay false vậy, nil được tạo ra từ lớp NilClass.

puts nil
p nil

p $val

p $val1 == $val2

Đoạn code trên thực hiện một số thao tác với nil.

puts nil
p nil

Phương thức puts sẽ in chuỗi rỗng của đối tượng nil, trong khi phương thức p lại in chuỗi "nil" ra màn hình.

p $val

Nếu chúng ta in một biến chưa có giá trị thì Ruby sẽ hiển thị là nil.

p $val1 == $val2

Dòng code trên sẽ trả về true vì đối tượng nil là một đối tượng tĩnh và nó chỉ có 1.


nil
nil
true

Kiểu chuỗi – String

Một string là một dãy các kí tự liên tiếp nhau. Trong Ruby chúng là các đối tượng thuộc lớp String. Các chuỗi string được bọc trong cặp dấu nháy đơn hoặc nháy kép.

String là một kiểu dữ liệu quan trọng, trong phần sau chúng ta sẽ tìm hiểu kĩ hơn về kiểu dữ liệu này.

p "Hello"
p 'Ruby'

p "Ruby".size
p "Ruby".upcase

p 2.to_s

Trong đoạn code trên chúng ta in một số string và các tính chất của chúng ra màn hình.

p "Hello"
p 'Ruby'

String có thể được bọc trong cặp dấu nháy đơn hoặc nháy kép.

p "Ruby".size
p "Ruby".upcase

Ở 2 dòng trên chúng ta gọi đến phương thức size và phương thức upcase, phương thức size trả về độ lớn của string còn phương thức upcase chuyển một string thành dạng chữ in hoa.

p 2.to_s

Trong dòng trên phương thức to_s chuyển một số thành một string.

"Hello"
"Ruby"
4
"RUBY"
"2"

Mảng và bảng băm

Mảng và bảng băm lưu dữ liệu theo dạng tập hợp, tức là chúng không lưu từng giá trị cụ thể mà lưu một nhóm các phần tử có giá trị khác nhau.

Mảng lưu các phần tử theo một thứ tự trong khi bảng băm lưu phần tử theo các cặp khóa-giá trị. Chúng ta sẽ tìm hiểu thêm về 2 kiểu dữ liệu này trong các bài sau.

nums = [1, 2, 3, 4]

puts "There are #{nums.size} items in the array"

nums.each do |num|
    puts num
end


domains = { :de => "Germany", :sk => "Slovakia",
            :us => "United States", :no => "Norway" }

puts domains.keys
puts domains.values

Đoạn code trên ví dụ về mảng và bảng băm trong Ruby.

nums = [1, 2, 3, 4]

puts "There are #{nums.size} items in the array"

nums.each do |num|
    puts num
end

Trong đoạn code trên, dòng đầu tiên tạo một mảng có 4 phần tử. Dòng thứ hai sẽ in số lượng phần tử trong mảng ra màn hình. Các dòng sau duyệt qua mảng để lấy từng phần tử của mảng và in ra màn hình.

domains = { :de => "Germany", :sk => "Slovakia",
            :us => "United States", :no => "Norway" }

puts domains.keys
puts domains.values

Ở đây chúng ta tạo một đối tượng bảng băm và in danh sách khóa và giá trị ra màn hình.

There are 4 items in the array
1
2
3
4
de
sk
us
no
Germany
Slovakia
United States
Norway

Chuyển đổi kiểu dữ liệu

Ruby có các phương thức hỗ trợ chuyển đổi kiểu dữ liệu như to_i, to_s hay to_f. Ngoài trong module Kernel còn có các phương thức như Integer, String hoặc Float cũng làm công việc tương tự.

p Array(1..6)
p Complex 6
p Float 12
p Integer "34"
p Rational 6
p String 22

Đoạn code trên chuyển đổi kiểu dữ liệu bằng các phương thức của module Kernel.

[1, 2, 3, 4, 5, 6]
(6+0i)
12.0
34
(6/1)
"22"

Đoạn code dưới đây chuyển đổi đối tượng sang kiểu số nguyên và số chấm động.

p "12".to_i
p 12.5.to_i
p nil.to_i

p 12.to_f
p "11".to_f
p nil.to_f

Một số đối tượng trong Ruby chứa phương thức to_ito_f giúp chuyển đổi sang kiểu số nguyên và số chấm động tương ứng.

12
12
0
12.0
11.0
0.0

Chúng ta có thể chuyển một string sang khá nhiều kiểu dữ liệu khác nhau:

p "12".to_i
p "13".to_f
p "12".to_r
p "13".to_c

p "Jane".to_sym

v = "Ruby Python Tcl PHP Perl".split
p v.class

Trong đoạn code trên chúng ta chuyển string sang số nguyên, số thực, số hữu tỉ, số phức, mảng và thậm chí là thành một symbol.

v = "Ruby Python Tcl PHP Perl".split
p v.class

Phương thức split sẽ tách từng kí tự trong string và lưu trong một mảng.

12
13.0
(12/1)
(13+0i)
:Jane
Array

Ruby – Kiểu dữ liệu – Phần 1

Trong phần này chúng ta sẽ tìm hiểu về các kiểu dữ liệu.

Tất cả các chương trình máy tính trên thế giới đều sử dụng dữ liệu, từ trình soạn thảo văn bản, máy tính, game… dữ liệu cũng được chia làm nhiều loại khác nhau chẳng hạn như số, kí tự, hình ảnh, âm thanh… Kiểu dữ liệu là một tập các giá trị và các thao tác có thể có trên các giá trị đó.

Tất cả các kiểu dữ liệu trong Ruby đều là lớp. Ruby hỗ trợ một số kiểu dữ liệu cơ bản sau đây:

  • Boolean – kiểu luận lý
  • Symbol
  • Number – số
  • String – chuỗi kí tự
  • Array – mảng
  • Hashe – bảng băm

Ví dụ:

h = { :name => "Jane", :age => 17 }

p true.class, false.class
p "Ruby".class
p 1.class
p 4.5.class
p 3_463_456_457.class
p :age.class
p [1, 2, 3].class
p h.class

Trong đoạn code trên chúng ta in tên lớp của từng kiểu dữ liệu khác nhau.

p true.class, false.class

Kiểu boolean có 2 giá trị là True hoặc False.

p "Ruby".class

Kiểu string, chúng ta đã làm việc với kiểu này trong các bài trước.

p 1.class
p 4.5.class
p 3_463_456_457.class

Kiểu số, gồm số nguyên và số thực.

p :age.class

Kiểu Symbol.

p [1, 2, 3].class
p h.class

Ở đây chúng ta có một đối tượng mảng và một đối tượng bảng băm.

TrueClass
FalseClass
String
Fixnum
Float
Bignum
Symbol
Array
Hash

Kiểu Boolean

Nói một cách “triết lý” thì trên thế giới này có một số thứ tồn tại theo 2 trạng thái/thái cực khác nhau… chẳng hạn như có Thiên đàng và Địa ngục, Nước và Lửa, Nam và Nữ… kiểu dữ liệu boolean cũng vậy, đối tượng thuộc kiểu này có một trong 2 trạng thái là True (đúng) hoặc False (sai). Đây là một kiểu dữ liệu quan trọng mà hầu hết ngôn ngữ lập trình nào cũng có.

Ví dụ:

bool = [true, false]

male = bool[rand(2)]


if male
    puts "We will use name John"
else 
    puts "We will use name Victoria"
end

Trong đoạn code trên chúng ta sử dụng phương thức rand() để lấy giá trị ngẫu nhiên từ 0→1.

bool = [true, false]

Chúng ta có một biến tên là bool, đây là một mảng có 2 giá trị là true hoặc false. Một mảng được tạo bằng cách sử dụng cặp dấu [].

male = bool[rand(2)]

Khi phương thức rand() trả về 0 hoặc 1, chúng ta dùng kết quả đó để lấy giá trị tương ứng trong mảng bool, tức là nếu 0 thì biến male có giá tri là true, nếu 1 thì malefalse.

if male
    puts "We will use name John"
else 
    puts "We will use name Victoria"
end

Tùy vào giá trị của male mà chúng ta in ra câu lệnh tương ứng với từ khóa if..else..end.

We will use name Victoria

Kiểu Symbol

Nếu bạn biết kiểu enum trong C++, Java… thì trong Ruby chúng được gọi là Symbol. Symbol được dùng để biểu diễn các đối tượng khác. Dùng symbol sẽ tiết kiệm được nhiều tài nguyên hơn so với dùng biến thông thường. Tất cả các biến symbol đều là một đối tượng từ lớp Symbol. Để định nghĩa một symbol thì chúng ta thêm dấu hai chấm ":" vào trước giá trị, ví dụ :name. Hầu hết các đối tượng trong Ruby đều có phương thức to_sym để chuyển một đối tượng thành một symbol.

Symbol không thể thay đổi được giá trị. Thường thì symbol được dùng để làm khóa trong bảng băm.

p :name
p :name.class
p :name.methods.size
p "Jane".methods.size

p :name.object_id
p :name.object_id
p "name".object_id
p "name".object_id

Trong đoạn code trên chúng ta thực hiện một số thao tác với symbol.

p :name
p :name.class

Chúng ta in symbol và tên của chúng ra màn hình.

p :name.methods.size
p "Jane".methods.size

Chúng ta so sánh kích thước dữ liệu của một symbol và một string. Rõ ràng là một string có kích thước lớn hơn một symbol.

p :name.object_id
p :name.object_id
p "name".object_id
p "name".object_id

Symbol giống nhau thì có id giống nhau, string giống nhau thì lại có id khác nhau.

:name
Symbol
79
162
10328
10328
77344750
77344730

Ngoài ra Symbol cũng thường được dùng để dánh dấu, chẳng hạn như thay vì khai báo biến number = 1 rồi thực hiện if number == 1... thì ở đây chúng ta dùng symbol sẽ tiết kiệm được bộ nhớ cũng như dễ code hơn.

light = :on

if light == :on
    puts "The light is on"
else
    puts "The light is off"
end

light = :off

if light == :on
    puts "The light is on"
else
    puts "The light is off"
end

Trong đoạn code trên chúng ta in các đoạn text khác nhau tùy theo giá trị của biến light.

Symbol còn được dùng để làm khóa trong bảng băm.

domains = {:sk => "Slovakia", :no => "Norway", :hu => "Hungary"}

puts domains[:sk]
puts domains[:no]
puts domains[:hu]

Trong đoạn code trên chúng ta có một đối tượng bảng băm là domains, đối tượng này dùng khóa là các Symbol.

puts domains[:sk]
puts domains[:no]
puts domains[:hu]

Chúng ta lấy giá trị của từng phần tử trong bảng băm bằng khóa.

Slovakia
Norway
Hungary

Kiểu số nguyên – Integer

Trong lập trình thì thì integer là một kiểu dữ liệu cơ bản, mặc dù trong toán thì số nguyên là  tập hợp Z, một tập hợp vô hạn, nhưng trong máy tính thì không có cái gì vô hạn cả, chúng ta có thể có tập hợp các số nguyên nhưng tập hợp này chỉ trong một phạm vi nhất định.

Trong Ruby thì số nguyên là các đối tượng thuộc lớp Fixnum hoặc Bignum, 2 lớp này có độ lớn khác nhau, độ lớn là khoảng giá trị của một đối tượng, ví dụ như trong C++, Java thì một số nguyên thường có độ lớn từ -2^32 đến 2^32, trong Ruby thì độ lớn của Fixnum tùy thuộc vào hệ điều hành, nếu một số nguyên có giá trị lớn hơn ngưỡng cho phép thì sẽ tự động được chuyển thành kiểu Bignum nên chúng ta cũng không cần phải quan tâm lắm đến vấn đề này.

p -2
p 121
p 123265
p -34253464356
p 34867367893463476

p 1.class
p 23453246.class
p 234532423563456346.class
p 2345324235632363463456456346.class

p 5 / 2
p 5.div 2

Đoạn code trên thực hiện một số thao tác với số nguyên.

p -2
p 121
p 123265
p -34253464356
p 34867367893463476

Trên đây là các con số cả âm lẫn không âm với các độ lớn khác nhau.

p 1.class
p 23453246.class
p 234532423563456346.class
p 2345324235632363463456456346.class

Chúng ta in ra tên lớp của các số nguyên. Hai số đầu tiên có kiểu Fixnum trong khi 2 số sau có kiểu Bignum.

p 5 / 2
p 5.div 2

Chúng ta thực hiện phép chia 2 số nguyên bằng toán tử / và phương thức div. Phép chia một số nguyên cũng sẽ trả về một số nguyên.

-2
121
123265
-34253464356
34867367893463476
Fixnum
Fixnum
Bignum
Bignum
2
2

Số nguyên còn có thể được biểu diễn trong nhiều hệ cơ số khác nhau như hệ thập phân (10), hệ thập lục phân (16), hệ bát phân (8), và hệ nhị phân (2). Hệ thập phân là hệ cơ số mà chúng ta thường dùng nhất, hệ thập lục phân được biểu diễn với kí tự 0x ở đầu, hệ bát phân dùng kí tự 0 và hệ nhị phân dùng kí tự 0b.

puts 122
puts 0x7a
puts 0172
puts 0b1111010

Đoạn code trên in số 122 ở bốn hệ cơ số khác nhau.

122
122
122
122

Bignum hay “số nguyên lớn” là các con số có số lượng chữ số rất lớn, thường là vài trăm chữ số, đọc số nguyên lớn cũng rất khó chịu, chẳng hạn như số 936758346345906394… do đó Ruby cho phép số nguyên lớn có thể có dấu gạch dưới “_” để chúng ta dễ đọc hơn, khi dịch thì trình thông dịch Ruby sẽ bỏ qua các dấu gạch dưới đó.

p 23482345629
p 23_482_345_629

p 23482345629 == 23_482_345_629

Đoạn code trên sử dụng dấu gạch dưới cho số nguyên lớn.

23482345629
23482345629
true

Số chấm động

Số chấm động tức là số thực, số thực thường được dùng để đo các giá trị liên tục như trọng lượng, tốc độ, chiều dài… Trong Ruby thì số thực được biểu diễn bởi lớp Float hoặc BigDecimal.

p 15.4
p 0.3455
p -343.4563

p 12.5.class
p -12.5.class
p (5.0 / 2).class

p 5.fdiv 2
p 12.to_f

Đoạn code trên thực hiện một số thao tác với số chấm động.

p 15.4
p 0.3455
p -343.4563

Chúng ta in 3 số chấm động, số chấm động có phần thập phân nằm phía sau dấu chấm.

p 12.5.class
p -12.5.class
p (5.0 / 2).class

Chúng ta in tên lớp biểu diễn số chấm động. Ngoài ra nếu chúng ta thực hiện tính toán một số nguyên với một số chấm động thì kết quả sẽ cho ra một số chấm động.

p 5.fdiv 2
p 12.to_f

Chúng ta tạo các số chấm động bằng phương thức fdiv và phương thức to_f. Phương thức fdiv chẳng qua là thực hiện phép chia nhưng trả về số chấm động mặc dù phép chia đó thực hiện trên 2 số nguyên, còn phương thức to_f sẽ chuyển đổi một số bất kì thành số thực.

15.4
0.3455
-343.4563
Float
Float
Float
2.5
12.0

Mặc định thì phần thập phân chỉ hiển thị tối đa 16 chữ số nhưng chúng ta có thể định dạng kiểu hiển thị theo ý chúng ta với phương thức sprintf hoặc printf.

p 1/3.0
p 1.fdiv 2

puts sprintf "%.4f" % (1/3.0)
puts sprintf "%.7f" % (5/3.0)

Đoạn code trên sẽ định dạng hiển thị số chấm động.

p 1/3.0
p 13.fdiv 4
p 1.fdiv 2

Phương thức p sẽ in các số chấm động một cách mặc định.

puts sprintf "%.4f" % (1/3.0)
puts sprintf "%.7f" % (5/3.0)

Chúng ta định dạng lại số chấm động bằng phương thức sprintf, phương thức này nhận vào một chuỗi định dạng, chuỗi này có dạng %... ở đây %.4f tức là hiển thị 4 chữ số phía sau dấu chấm, tương tự %.7f là hiển thị 7 chữ số, kí tự f cho Ruby biết kiểu định dạng này được sử dụng với số chấm động.

0.3333333333333333
3.25
0.5
0.3333
1.6666667

 

Ruby – Đối tượng

Trong phần này chúng ta sẽ tìm hiểu sơ qua về đối tượng trong Ruby, các bài sau sẽ trình bày chi tiết hơn.

Ruby là một ngôn ngữ lập trình hướng đối tượng. Tất cả mọi thứ trong Ruby đều là đối tượng. Các đối tượng trong Ruby tồn tại trong suốt quá trình biên dịch code. Có 2 loại đối tượng là đối tượng có sẵn và đối tượng do chúng ta định nghĩa. Đối tượng có sẵn là các đối tượng đã được định nghĩa sẵn trong Ruby hoặc các thư viện do người khác viết bằng Ruby và chúng ta có thể sử dụng. Còn loại kia là đối tượng do chúng ta định nghĩa để sử dụng với công việc đặc thù của riêng chúng ta khi các đối tượng có sẵn không đáp ứng được.

Muốn sử dụng đối tượng thì chúng ta phải khởi tạo trước. Một đối tượng chứa thuộc tính và phương thức bên trong nó. Thuộc tính là dữ liệu của đối tượng, đây là thành phần tĩnh, phương thức là phần động. Đối tượng có thể được chỉnh sửa hoặc giao tiếp với các đối tượng khác thông qua phương thức.

puts "Ruby language"

Nếu bạn đã từng lập trình C++, Java thì bạn cũng đã biết tới những từ khóa hoặc hàm dùng để in một chuỗi ra màn hìnhchẳng hạn như hàm printf() trong C, std::cout trong C++, System.out.println() trong Java… các hàm này có chức năng là in một chuỗi ra màn hình, từ khóa puts trong Ruby ở trên cũng có chức năng tương tự. Các từ khóa/hàm này nhận vào một giá trị là một chuỗi, trong ví dụ trên thì “Ruby language” là một giá trị,

Nhưng trong Ruby thì có hơi khác, bản thân chuỗi “Ruby language” cũng là một đối tượng. Do đó chúng ta cũng có thể gọi phương thức từ chuỗi này.

Ngoài ra phương thức tồn tại trong các đối tượng chứ không tự tồn tại một mình ở đâu đó được, puts cũng là một phương thức của một đối tượng đó là module Kernel.

Ví dụ 1:

Kernel.puts "Ruby language"
Kernel.puts "Ruby language".size

Trong dòng code đầu tiên chúng ta gọi phương thức puts và gọi cả tên module Kernel ra luôn. Trong C# hay Java cũng tương tự là Console.writelnSystem.out.println(). Tất nhiên là chúng ta cũng không cần gọi Kernel ra như vậy trong Ruby nhưng ví dụ này chỉ để khẳng định là phương thức thì luôn đi kèm với một đối tượng nào đó.

Trong dòng tiếp theo chúng ta in ra kích thước của chuỗi “Ruby language”, điều này chứng tỏ chuỗi “Ruby language” cũng chính là một đối tượng chứ không đơn thuần chỉ là một giá trị như trong các ngôn ngữ khác. Phương thức size sẽ trả về số lượng kí tự trong một chuỗi.

Ruby language
13

Ví dụ 2:


puts 6.object_id

puts 6.even?
puts 6.zero?

puts 6.class

Chúng ta có số 6 và cũng có thể gọi một số phương thức của số 6 này.

puts 6.object_id

Mỗi đối tượng đều được gán một id và chúng ta có thể lấy giá trị đó ra bằng cách gọi phương thức object_id. Mỗi lời gọi phương thức đều được đặt sau dấu chấm sau tên đối tượng.

puts 6.even?
puts 6.zero?

Phương thức even? trả về True nếu số đó là số chẵn và ngược lại. Phương thức zero? trả về True nếu số đó là 0. Ở đây có một điểm lưu ý là nếu phương thức trả về True hoặc False thì phải kèm thêm dấu ? sau tên phương thức.

puts 6.class

Phương thức class cho biết tên lớp của đối tượng, ở đây số 6 là một đối tượng thuộc lớp Fixnum.

13
true
false
Fixnum

Tạo đối tượng

Một đối tượng phải được tạo ra thì mới có thể sử dụng được. Đối tượng trong Ruby có thể được tạo ra một cách rõ ràng hoặc tạo ngầm. Ví dụ về đối tượng ngầm là mấy cái đối tượng được tạo ra từ giá trị như số 6 hay chuỗi “Ruby language” ở trên. Còn để tạo đối tượng một cách rõ ràng thì chúng ta dùng từ khóa new. Đối tượng thuộc lớp do chúng ta tự định nhĩa cũng dùng từ khóa new.


class Being
end
    
puts 67
puts "Hello world"

s = String.new "Hello world"
puts s

# n1 = Fixnum.new 67
# puts n1

b = Being.new
puts b

Trong đoạn code trên chúng ta tạo một số đối tượng bằng các cách khác nhau.

class Being
end

Chúng ta định nghĩa lớp Being. Để định nghĩa một lớp thì chúng ta dùng từ khóa class.

puts 67
puts "Hello world"

Hai dòng code trên tạo đối tượng ngầm là 67 và chuỗi “Hello world”.

s = String.new "Hello world"
puts s

Tương tự, chúng ta có thể tạo đối tượng string một cách rõ ràng luôn với từ khóa new.

# n1 = Fixnum.new 67
# puts n1

Không phải tất cả các lớp có sẵn trong Ruby đều có thể được tạo ra bằng từ khóa new, Fixnum là một ví dụ, các đối tượng Fixnum chỉ có thể được tạo ngầm.

b = Being.new
puts b

Đoạn code trên tạo đối tượng b từ lớp Being do chúng ta định nghĩa.

67
Hello world
Hello world
#<Being:0x8492o3a>

Đối tượng giá trị

Như đã nói ở trên là chúng ta có thể tạo đối tượng một cách ngầm định từ các giá trị. Ở đây chúng ta sẽ làm việc với một số phương thức của loại đối tượng này.

4.times { puts "Ruby" }

puts "Ruby".size
puts "Ruby".downcase

puts [1, 2, 3].include? 3
puts [1, 2, 3].empty?

puts :name.class
puts :name.frozen?

puts (1..6).class
puts (1..6).include? 4

Trong đoạn code trên chúng ta có các đối tượng Fixnum, String, Array, kiểu Symbol và kiểu Range. Chúng ta sẽ tìm hiểu kỹ hơn về các kiểu đối tượng này trong bài sau.

4.times { puts "Ruby" }

Phương thức times của đối tượng Fixnum thực hiện phép nhân lên giá trị phía sau nó, ở đây là thực hiện puts "Ruby" 4 lần.

puts "Ruby".size
puts "Ruby".downcase

Phương thức size lấy về số kí tự trong chuỗi, phương thức downcase thực hiện chuyển chuỗi về kiểu chữ in thường.

puts [1, 2, 3].include? 3
puts [1, 2, 3].empty?

Trong 2 dòng code trên chúng ta sử dụng đối tượng kiểu mảng – Array, phương thức include? cho biết một giá trị nào đó có thuộc mảng hay không. Phương thức empty? cho biết mảng này rỗng hay không.

puts :name.class
puts :name.frozen?

Ở 2 dòng trên chúng ta thao tác với kiểu Symbol, symbol có tên bắt đầu bằng dấu 2 chấm ":" chúng ta sẽ tìm hiểu thêm trong bài sau.

puts (1..6).class
puts (1..6).include? 4

Cuối cùng là 2 đối tượng kiểu Range, về bản chất thì kiểu này cũng tương tự như kiểu mảng vậy. Phương thức class trả về tên của kiểu dữ liệu này, còn phương thức include? cho biết giá trị nào đó có nằm trong danh sách hay không.

Ruby
Ruby
Ruby
Ruby
4
ruby
true
false
Symbol
false
Range
true

Thừa kế

Một trong những khái niệm trong lập trình hướng đối tượng là thừa kế và Ruby cũng thế. Thừa kế bao gồm các đối tượng cha và đối tượng con, đối tượng cha sẽ chứa những thuộc tính và phương thức mà đối tượng con có thể thừa kế lại. Tất cả các đối tượng trong Ruby đều thừa kế từ một đối tượng gốc có tên là Object. Tất cả các đối tượng trong Ruby đều có các phương thức mà đối tượng Object có, nhưng có thể định nghĩa lại.

puts 4.is_a? Object
puts "Ruby".is_a? Object
puts [2, 3].is_a? Object
puts :name.is_a? Object
puts (1..2).is_a? Object

Đoạn code trên cho chúng ta thấy tất cả các đối tượng đều thừa kế từ đối tượng Object.

puts 4.is_a? Object

Trong dòng code trên phương thức is_a? cho biết đối tượng 4 có được kế thừa từ đối tượng Object hay không.

true
true
true
true
true

Trong ví dụ dưới đây, chúng ta sẽ định nghĩa các lớp có kế thừa nhau.

class Being

    def to_s
        "This is Being"
    end
    
    def get_id
        9
    end
end

class Living < Being
    
    def to_s
        "This is Living"
    end
end

l = Living.new

puts l
puts l.get_id
puts l.is_a? Being

Chúng ta định nghĩa 2 lớp BeingLiving, lớp Living kế thừa từ lớp Being, do đó lớp Being là lớp cha, lớp Living là lớp con.

class Being

    def to_s
        "This is Being"
    end
    
    def get_id
        9
    end
end

Để định nghĩa một lớp thì chúng ta sử dụng cặp từ khóa class...end, sau từ khóa class là tên lớp mà chúng ta muốn đặt. Bên trong lớp chúng ta có thể định nghĩa các phương thức bằng cách dùng cặp từ khóa def…end, sau từ khóa def cũng từ tên phương thức mà chúng ta muốn đặt. Trong đoạn code trên chúng ta có 2 phương thức là to_sget_id.

Đối tượng nào cũng có phương thức to_s cả vì mặc định đối tượng Object cũng có phương thức này. Khi chúng ta dùng phương thức puts để in ra một giá trị nào đó thì phương thức này sẽ tự động gọi đến phương thức to_s có trong các đối tượng. Trong ví dụ này chúng ta định nghĩa lại phương thức to_s, nếu không thì puts sẽ sử dụng phương thức to_s mặc định của đối tượng Object.

class Living < Being
    
    def to_s
        "This is Living"
    end
end

Chúng ta định nghĩa lớp Living, lớp này kế thừa từ lớp Being, để một lớp được kế thừa từ lớp khác thì chúng ta thêm dấu < cùng với tên của lớp cha vào sau tên lớp con. Ở đây lớp Living cũng định nghĩa lại phương thức to_s của riêng nó.

l = Living.new

Chúng ta tạo đối tượng Living bằng cách dùng từ khóa new.

puts l

Phương thức puts sẽ gọi đến phương thức to_s trong lớp Living.

puts l.get_id

Lớp Living không định nghĩa lại phương thức get_id nên Ruby sẽ tìm dần dần các lớp cha xem lớp nào có thì gọi phương thức get_id từ lớp đó.

puts l.is_a? Being

Dòng code trên sẽ trả về True vì lớp Living kế thừa từ lớp Being nên một đối tượng Living cũng là một đối tượng Being.

This is Living
9
true

Đối tượng main

Trong các ngôn ngữ như C++, Java… thì chương trình bắt đầu chạy từ một hàm đặc biệt tên là hàm main(), khi chạy chương trình hàm này sẽ được gọi từ hệ điều hành.

Trong Ruby cũng thế, mỗi đoạn code trong file .rb đều nằm trong một đối tượng có tên là main mặc dù ở đây chúng ta không khai báo ra, đối tượng này cũng kế thừa từ đối tượng Object. Chính vì main cũng là một đối tượng nên các biến được khai báo trong main cũng là thuộc tính của main.

n1 = 3
n2 = 5

puts local_variables

Kernel.puts self
puts self.class

Đoạn code trên ví dụ về đối tượng main trong Ruby.

n1 = 3
n2 = 5

Chúng ta có 2 đối tượng số nguyên. Cả hai đối tượng này đều thuộc về đối tượng main.

puts local_variables

Biến local_variables thực chất là một phương thức của module Kernel, lưu trữ danh sách các biến cục bộ hiện có.

Kernel.puts self

Biến self là biến tham chiếu đến đối tượng hiện tại, nói cho dễ hiểu thì self chính là main, nếu bạn biết con trỏ this trong C++, Java… thì self cũng giống như con trỏ this vậy.

puts self.class

Biến class cho biết tên lớp của đối tượng hiện tại, hiện tại chúng ta dùng đối tượng self (hoặc main) mà đây là đối tượng thuộc lớp Object nên dòng trên sẽ in ra chuỗi Object.

n1
n2
main
Object

 

Ruby – Biến

Biến là nơi lưu trữ dữ liệu. Mỗi biến có một tên riêng, tên biến được đặt theo một số quy luật riêng. Mỗi biến có một kiểu dữ liệu riêng. Ruby có rất nhiều kiểu dữ liệu có sẵn. Kiểu dữ liệu trong Ruby là kiểu dữ liệu động, tức là khi chúng ta khai báo biến và gán giá trị thì Ruby sẽ tự động gán kiểu dữ liệu cho biến dựa trên giá trị đó chứ chúng ta không cần phải khai báo trước kiểu dữ liệu như trong các ngôn ngữ như C++, Java…


i = 5
puts i
i = 7
puts i

Giá trị của biến có thể thay đổi được. Trong đoạn code trên chúng ta có biến i có giá trị ban đầu là 5, sau đó thay bằng 7.

Quy tắc đặt tên biến

Tên biến là có phân biệt HOA-thường. Tức là biến age và biến Age là 2 biến khác nhau.


i = 5
p i
I = 7
p I

Trong đoạn code trên chúng ta có biến i và biến I mang các giá trị khác nhau.

5
7

Biến được đặt tên bằng các kí tự chữ cái, chữ số và dấu gạch dưới “_”, nhưng không thể bắt đầu bằng chữ số và chữ cái in hoa.


name = "Jane"
placeOfBirth = "Bratislava"
placeOfBirth = "Kosice"
favorite_season = "autumn"

n1 = 2
n2 = 4
n3 = 7

p name, placeOfBirth, favorite_season
p n1, n2, n3

Trong đoạn code trên n1, n2n3 là các tên biến hợp lệ.

Khi đặt tên biến chúng ta nên đặt tên sao cho dễ nhớ và dễ sử dụng.

Sigil

Biến trong Ruby có thể bắt đầu bằng một số kí tự đặc biệt và được gọi là sigil, các kí tự sigil dùng để chỉ ra phạm vi hoạt động của biến.


tree_name = "pine"
$car_name = "Peugeot"
@sea_name = "Black sea"
@@species = "Cat"

p local_variables
p global_variables.include? :$car_name
p self.instance_variables
p Object.class_variables

Trong đoạn code trên chúng ta có 4 biến với 4 phạm vi hoạt động khác nhau tùy theo từng kí hiệu sigil.

tree_name = "pine"

Biến không có kí tự đặc biệt nào được gọi là biến cục bộ, tức là chỉ có hiệu lực ở phạm vi trong từng phương thức, lớp… nhất định.

$car_name = "Peugeot"

Kí tự $ cho biết biến đó là biến toàn cục, biến toàn cục có hiệu lực trong toàn bộ code Ruby.

@sea_name = "Black sea"

Kí tự @ cho biết biến đó là biến instance, biến này chỉ có hiệu lực trong một đối tượng.

@@species = "Cat"

Cuối cùng là kí tự @@ tức biến class, tất cả các đối tượng của một class đều có thể truy xuất biến này.

Chúng ta sẽ tìm hiểu thêm về các loại biến này ở dưới và trong các bài sau.

p local_variables

Biến local_variables là một mảng lưu trữ toàn bộ các biến cục bộ hiện có.

p global_variables.include? :$car_name

Tương tự, chúng ta có biến global_variables lưu toàn bộ các biến toàn cục, nhưng ở đây chúng ta không cho in ra toàn bộ vì số lượng biến toàn cục có sẵn rất nhiều, thay vào đó chúng ta dùng phương thức include? để kiểm tra xem biến $car_name của chúng ta có nằm trong danh sách đó hay không.

p self.instance_variables

Ở trên chúng ta tham chiếu đến biến instance_variables, biến này lưu trữ toàn bộ biến instance trong đối tượng hiện tại, ở đây là những biến instance được khai báo trong chương trình – tức là @sea_name.

Ngoài ra ở đây chúng ta còn dùng thêm biến self nữa, biến self tham chiếu đến đối tượng hiện tại đang được sử dụng, ở đây là chương trình chính, nếu bạn đã từng làm việc với con trỏ this trong C++, Java… thì self cũng giống như con trỏ this vậy. Thực ra ở đây bạn cũng không cần dùng đến self vì chúng ta đang gọi hàm ngay trong chương trình chính chứ không phải bên trong một phương thức hay lớp nào đó.

p Object.class_variables

Cuối cùng là biến class_variables,  biến này lưu trữ toàn bộ biến class có trong chương trình.

[:tree_name]
true
[:@sea_name]
[:@@species]

Biến cục bộ

Biến cục bộ là biến chỉ có hiệu lực trong một phạm vi nhất định trong toàn bộ code Ruby, cụ thể là biến nằm bên trong hàm, phương thức, class.

def method1
   x = 5
   p x    
end

method1 

p x

Trong đoạn code trên chúng ta có phương thức method1 có một biến là x, biến này là biến cục bộ, chúng ta chỉ có thể sử dụng biến này giữa cặp từ khóa def...end.

method1 

Chúng ta gọi phương thức bằng cách ghi rõ tên phương thức ra.

p x

Nếu chúng ta truy xuất biến ở ngoài phạm vi phương thức thì Ruby sẽ báo lỗi NameError vì Ruby không tìm thấy biến đó.

5
./locals.rb:11:in `<main>': undefined local variable 
or method `x' for main:Object (NameError)

Đoạn code dưới đây chỉnh sửa lại từ đoạn code trên một tí.


x = 5

def method1
    x = 10
    p x
end

method1

p x

Trong đoạn code trên chúng ta có 2 biến tên là x, một biến nằm trong phương thức method1 và một biến nằm ở ngoài, mặc dù chúng có cùng tên nhưng đây là 2 biến khác nhau hoàn toàn.

x = 5

Biến x đầu tiên được gán giá trị là 5, biến này có phạm vi trong toàn đoạn code nhưng không thể truy cập ở bên trong phương thức method1.

def method1
    x = 10
    p x
end

Bên trong phươn thức method1 lại có một biến x khác nữa được gán giá trị là 10. Biến này chỉ có hiệu lực bên trong cặp từ khóa def...end.

10
5

Phương thức có thể nhận vào các tham số, các tham số khi truyền vào phương thức sẽ có hiệu lực như một biến cục bộ bên trong phương thức đó:


def rectangle_area a, b
    puts local_variables
    return a * b
end

puts rectangle_area 5, 6

Ở trên chúng ta có phương thức rectangle_area nhận vào 2 tham số ab. Phương thức này tính và trả về diện tích hình chữ nhật.

puts rectangle_area 5, 6

Để truyền tham số vào phương thức thì chúng ta ghi giá trị hoặc biến vào sau lời gọi phương thức.

a
b
30

Một phương thức có thể được định nghĩa bên trong một phương thức khác, phương thức đó gọi là phương thức nội, phương thức nội cũng có biến cục bộ của riêng nó.

def method1
    
    def method2
                
        def method3
            m5, m6 = 3
            puts "Level 3"
            puts local_variables
        end            
        
        m3, m4 = 3
        puts "Level 2"
        puts local_variables
        method3    
    end        
    
    m1, m2 = 3
    puts "Level 1"
    puts local_variables
    method2
            
end

method1

Trong đoạn code trên chúng ta định nghĩa 3 phương thức là method1, method2method3, trong đó method2method3 là các phương thức nội. Phương thức method2 nằm bên trong method1method3 lại nằm bên trong method2. Các biến nằm ở phương thức nào thì chỉ có hiệu lực ở phạm vi phương thức đó.

Level 1
m1
m2
Level 2
m3
m4
Level 3
m5
m6

Biến toàn cục

Biến toàn cục khác biến cục bộ ở chỗ là có hiệu lực trên toàn code. Biến toàn cục có tên bắt đầu bằng ký tự $.


$gb = 6


module ModuleM        
    puts "Inside module"
    puts $gb
end


def method1
    puts "Inside method"
    puts $gb
end


class Some
    puts "Inside class"
    puts $gb
end 

method1

puts "Inside toplevel"
puts $gb
puts global_variables.include? :$gb

Trong đoạn code trên chúng ta có biến toàn cục $gb. Biến toàn cục có thể sử dụng được trong cả module, phương thức, lớp…

$gb = 6

Chúng ta khai báo biến toàn cục $gb và gán giá trị là 6.

module ModuleM        
    puts "Inside module"
    puts $gb
end

Trong module ModuleM chúng ta in giá trị của biến toàn cục.

def method1
    puts "Inside method"
    puts $gb
end

Trong phương thức method1 cũng vậy.

class Some
    puts "Inside class"
    puts $gb
end

Và cả bên trong class cũng vậy.

puts $gb
puts global_variables.include? :$gb

Ở ngoài các phương thức, class… chúng ta cũng có thể gọi đến biến toàn cục $gb.

Inside module
6
Inside class
6
Inside method
6
Inside toplevel
6
true

Ngoài các biến toàn cục do chúng ta định nghĩa, Ruby còn có sẵn các biến được định nghĩa sẵn.

p $LOAD_PATH
p $:

Ở trên chúng ta dùng 2 biến $LOAD_PATH$:, đây đều là các biến lưu trữ thông tin về các đường dẫn thư mục có trong biến môi trường Path của Windows.

Biến instance và biến class

Ở đây chúng ta sẽ tìm hiểu sơ qua về biến instance và biến class. Chúng ta sẽ tìm hiểu thêm trong bài hướng đối tượng.

Biến instance là biến nằm trong một đối tượng cụ thể. Mỗi đối tượng có những biến instance riêng của chúng, biến instance có tên bắt đầu bằng kí tự @.

Biến class là biến nằm trong một lớp. Những đối tượng được tạo ra từ lớp đó sẽ dùng chung biến class, biến class có tên bắt đầu bằng kí tự @@.

class Being
    
    @@is = true
       
    def initialize nm
        @name = nm
    end
    
    def to_s
        "This is #{@name}"
    end    
    
    def does_exist?
        @@is
    end
end

b1 = Being.new "Being 1"
b2 = Being.new "Being 2"
b3 = Being.new "Being 3"

puts b1, b2, b3

p b1.does_exist?
p b2.does_exist?
p b3.does_exist?

Trong đoạn code trên chúng ta định nghĩa lớp Being. Lớp này có một biến instance và một biến class.

class Being
    
    @@is = true

Biến @@is là một biến class, tất cả các đối tượng thuộc lớp Being đều dùng chung một biến @@is.

def initialize nm
    @name = nm
end

Phương thức initialize là phương thức khởi tạo. Phương thức này tự động được gọi khi chúng ta khai báo đối tượng. Mỗi đối tượng thuộc lớp Being có biến instance @name khác nhau.

def to_s
    "This is #{@name}"
end       

Phương thức to_s tự động được gọi khi dùng với hàm như p hay puts. Ở đây phương thức này trả về một chuỗi.

def does_exist?
    @@is
end

Phương thức does_exist? trả về biến class của lớp đó.

b1 = Being.new "Being 1"
b2 = Being.new "Being 2"
b3 = Being.new "Being 3"

Sau khi đã định nghĩa lớp, chúng ta khai báo 3 đối tượng thuộc lớp Beingb1, b2b3. Mỗi đối tượng khi khởi tạo được nhận một tham số dùng cho biến @name của riêng chúng.

puts b1, b2, b3

Phương thức puts sẽ tự động gọi đến phương thức to_s tương ứng với từng đối tượng.

p b1.does_exist?
p b2.does_exist?
p b3.does_exist?

Phương thức does_exist? sẽ trả về giá trị của biến @@is, do cả 3 đối tượng này đều dùng chung biến class @@is nên kết quả trả về là như nhau.

This is Being 1
This is Being 2
This is Being 3
true
true
true

Ruby – Cơ bản

Trong phần này chúng ta sẽ học cách làm việc với ngôn ngữ Ruby.

Ví dụ một đoạn code Ruby:

puts "This is Ruby"

Đoạn code trên rất đơn giản, chỉ là in chuỗi “This is Ruby” ra màn hình console. Từ khóa puts nhận vào một tham số phía sau nó là một chuỗi text, chuỗi text được bọc trong cặp dấu nháy kép "".

This is Ruby

Đọc dữ liệu vào từ terminal (trong Windows là Command Promptcmd):

print "What is your name? "
name = gets

puts "Hello #{name}"

Đoạn code trên sẽ nhận một chuỗi do chúng ta nhập vào từ bàn phím rồi in ra màn hình.

print "What is your name? "

Từ khóa print cũng có tác dụng in một chuỗi text lên màn hình nhưng không xuống dòng như từ khóa puts.

name = gets

Dòng code trên sẽ đọc một đoạn text từ người dùng và lưu vào biến name bằng cách sử dụng phương thức gets,

puts "Hello #{name}"

#{name} sẽ thay bằng giá trị của biến name, bằng cách đó chúng ta có thể đưa giá trị của biến vào trong chuỗi.

What is your name? Pho Code
Hello Pho Code

Ngoài cách chạy code Ruby từ file script thì chúng ta cũng có thể chạy code từng dòng trong terminal:

C:\User\PhoCode>ruby -e "puts RUBY_VERSION"
2.2.4

Khi chúng ta chạy code Ruby từ file script, chẳng hạn như ruby hello.rb thì trình thông dịch Ruby sẽ đọc và dịch code trong file hello.rb, còn nếu chúng ta đưa vào tham số -e thì Ruby sẽ thực thi đoạn lệnh phía sau chứ không tìm file để chạy.

Ngoài ra trình thông dịch Ruby còn có tham số -c, khi dùng tham số này thì trình thông dịch Ruby sẽ thực hiện kiểm tra lỗi cú pháp của đoạn code chứ không thực hiện đoạn code bên trong, nếu không có lỗi thì sẽ in đoạn text “Syntax OK” ra màn hình.

puts "This is Ruby

Đoạn có trên có lỗi cú pháp là thiếu dấu " kết thúc chuỗi.

C:\User\PhoCode>ruby -c syntax_check.rb 
syntax_check.rb:1: unterminated string meets end of file

Trình thông dịch sẽ báo lỗi nếu có lỗi.

Đưa tham số vào chương trình

Khi chúng ta chạy một file script Ruby thì có thể đưa các tham số vào chương trình để sử dụng.

puts ARGV

Trong Ruby biến toàn cục ARGV là biến lưu các tham số được truyền vào chương trình, đây là một mảng, mỗi phần tử trong mảng là một tham số.

puts ARGV

Chúng ta in toàn bộ tham số được đưa vào chương trình.

C:\User\PhoCode>ruby args.rb 1 2 3
1
2
3

Chúng ta truyền tham số vào bằng cách gõ các giá trị vào sau tên file script. Trong đoạn code trên chúng ta truyền vào 3 con số.

Ngoài ra chúng ta có thể lấy từng tham số đơn lẻ:

puts $0
puts $*

Trong Ruby các biến toàn cục có tên bắt đầu bằng kí tự $ theo sau là tên biến. Ngoài ra Ruby còn có sẵn một số biến đặc biệt, chẳng hạn như $0 lưu tên file script được thực thi, $* cũng lưu các tham số truyền vào như ARGV.

C:\User\PhoCode>ruby args2.rb Ruby Python Perl
Ruby
Python
Perl

Biến và hằng số

Biến là nơi để lưu trữ dữ liệu. Biến gồm có tên và kiểu dữ liệu, kiểu dữ liệu là các loại giá trị khác nhau, ví dụ như số nguyên, chuỗi, số thực… là các loại kiểu dữ liệu khác nhau. Không giống các ngôn ngữ như C++, Java… bạn phải khai báo rõ ràng kiểu dữ liệu cùng tên biến như int a, Ruby là ngôn ngữ động, tức là bạn chỉ cần khai báo tên biến và gán giá trị cho nó là Ruby sẽ tự quy định kiểu dữ liệu, ngoài ra bạn cũng có thể thay đổi giá trị và Ruby cũng sẽ tự động thay đổi kiểu dữ liệu cho bạn luôn.

Hằng số trong Ruby cũng khác với các ngôn ngữ khác, trong các ngôn ngữ như C++, Java… thì hằng số là không thể thay đổi được giá trị, còn hằng số trong Ruby thì có thể thay đổi được, khi dịch thì Ruby không báo lỗi mà chỉ đưa ra các lời cảnh báo.

city = "New York"
name = "Paul"; age = 35
nationality = "American"

puts city
puts name
puts age
puts nationality

city = "London"

puts city

Trong đoạn code trên chúng ta làm việc với 4 biến.

city = "New York"

Biến city lưu trữ một chuỗi text, Ruby tự động nhận diện kiểu dữ liệu.

name = "Paul"; age = 35

Khi khai báo nhiều biến trên cùng một dòng thì chúng ta phải ngăn cách chúng bằng dấu chấm phẩy. Trong thực tế thì tốt hơn hết là chúng ta khai báo trên nhiều dòng khác nhau.

puts city
puts name
puts age
puts nationality

Chúng ta in các biến ra màn hình

city = "London"

Đoạn code trên sẽ gán lại giá trị mới cho biến city.

C:\User\PhoCode>ruby variables.rb 
New York
Paul
35
American
London

Trong đoạn code dưới đây chúng ta sẽ làm việc với hằng số.

WIDTH = 100
HEIGHT = 150

var = 40
puts var

var = 50
puts var

puts WIDTH
WIDTH = 110
puts WIDTH

Chúng ta khai báo 2 hằng và một biến.

WIDTH = 100
HEIGHT = 150

Chúng ta chỉ cần đặt tên với chữ cái đầu viết hoa thì biến đó sẽ là hằng số. Trong thực tế thì chúng ta nên viết hoa toàn bộ các chữ cái trong tên hằng.

C:\User\PhoCode>ruby constants.rb 
40
50
100
constants.rb:13: warning: already initialized constant WIDTH
110

Ruby – Các thành phần của Ruby

Một ngôn ngữ lập trình bao gồm nhiều thành phần cấu thành nên nó. Trong phần này chúng ta sẽ tìm hiểu các thành phần cấu tạo nên ngôn ngữ lập trình Ruby.

Bình luận – Comment

Các đoạn comment được dùng để ghi chú mã nguồn. Cú pháp comment của Ruby có 2 loại là comment cho một dòng và comment cho nhiều dòng. Comment trên một dòng được bắt đầu bởi dấu #, comment trên nhiều dòng được bọc bởi cặp kí hiệu =begin=end.

=begin
  comments.rb
  Pho Code
=end

puts "Comments example"

Các dòng comment sẽ không được dịch bởi trình thông dịch.

=begin
  comments.rb
  Pho Code
=end

Biến – Variable

Biến chỉ là một cái tên, đại diện cho một thứ gì đó có công việc là lưu trữ một giá trị nào đó. Trong lập trình thì chúng ta nói là “gán giá trị cho biến”, giá trị ở đây có thể là một đoạn text, một con số hay một đối tượng nào đó.

Tên của các biến được đặt bằng các kí tự trong bảng chữ cái và dấu gạch dưới, nhưng không được bắt đầu bằng kí tự số, cũng không được bắt đầu bằng kí tự viết HOA, nếu dùng chữ HOA thì Ruby sẽ gọi đây là “hằng số”.

Value
value2
company_name

Value là một hằng số, value2company_name là biến.

12Val
exx$
first-name

Ở trên là các tên biến không hợp lệ.

Tên biến có thể được bắt đầu bởi 2 kí tự đặc biệt là @$chúng ta sẽ tìm hiểu thêm sau.

Biến trong Ruby là có phân biệt HOA-thường, tức là pricepRice là 2 biến khác nhau.

Hằng số – Constant

Trong các ngôn ngữ khác thì hằng số cũng là các biến thôi nhưng chỉ lưu một giá trị trong suốt chương trình, không thể thay đổi được. Nhưng không giống với các ngôn ngữ khác, giá trị của các hằng số trong Ruby là có thể thay đổi được, khi chúng ta thay đổi giá trị hằng thì Ruby không báo lỗi mà chỉ đưa ra mấy dòng cảnh báo.

Tên hằng số được bắt đầu bởi một kí tự viết HOA, thường thì khi đặt tên hằng chúng ta luôn viết hoa toàn bộ các kí tự trong tên.

Name = "Robert"
AGE = 23

Name = "Juliet"

Trong ví dụ trên chúng ta định nghĩa hằng NameAGE, sau đó thay đổi giá trị của Name và Ruby sẽ báo lỗi tương tự như sau.

C:\Project\Ruby>irb constants.rb
constants.rb:4: warning: already initialized constant Name

Giá trị – Literal

Giá trị là các kí tự mô tả một giá trị của một kiểu dữ liệu nào đó, có thể là một con số, một đoạn text… dùng để gán cho các biến. Chúng ta sẽ tìm hiểu về kiểu dữ liệu sau.

age = 29
nationality = "Hungarian"

Trong ví dụ trên thì 29“Hungarian” là giá trị, agenationality là biến.

require 'date'

sng = true
name = "James"
job = nil
weight = 68.5
born = Date.parse("November 12, 1986")

puts "His name is #{name}"

if sng == true
    puts "He is single"
else
    puts "He is in a relationship"
end

puts "His job is #{job}"
puts "He weighs #{weight} kilograms"
puts "He was born in #{born}"

Trong đoạn code trên thì chúng ta có các giá trị có kiểu dữ liệu boolean, kiểu string, kiểu float, kiểu nil – có thể hiểu là kiểu rỗng, kiểu Date.

His name is James
He is single
His job is 
He weighs 68.5 kilograms
He was born in 1986-11-12

Khối lệnh – Block

Khối lệnh là cách để chúng ta gộp nhóm các lênh lại với nhau, bạn sẽ hiểu về khối lệnh nhiều hơn khi thực hành. Khối lệnh trong Ruby được bắt đầu và kết thúc bởi cặp dấu {} hoặc cặp từ khóa do-end.

puts [2, -1, -4, 0].delete_if { |x| x < 0 }
    
[1, 2, 3].each do |e|
    puts e
end

Trong ví dụ trên chúng ta sử dụng cả 2 loại khối lệnh.

Ngoài các câu lệnh tính toán bình thường thì trong lập trình còn có các câu lệnh điều khiển, ví dụ như câu lệnh if, đây là câu lệnh điều kiện, theo sau if là một biểu thức rồi tới một khối lệnh nằm trong cặp từ khóa then-end. Chúng ta sẽ tìm hiểu thêm về các câu lệnh điều kiện sau.

if true then
    puts "Ruby language"
    puts "Ruby script"
end

Sigil

Sigil là các kí tự $@ dùng để khai báo phạm vi hoạt động của biến. Trong đó $ cho biết biến đó là một biến toàn cục, @ cho biết đó là biến instance, @@ là biến class. Chúng ta sẽ tìm hiểu thêm trong bài lập trình hướng đối tượng.

$car_name = "Peugeot"
@sea_name = "Black sea"
@@species = "Cat"

Sigil luôn được đặt trước tên biến.

Toán tử

Toán tử là các kí tự thực hiện các hành động nào đó trên một giá trị nào đó.

!    +    -    ~    *    **    /    %
<< >>    &    |    ^
==    ===    !=    <=>    >=    >
<    <=    =    %=    /=    -=
+=    *=    **=    ..    ...    not
and    or    ?:    &&    || 

Chúng ta sẽ tìm hiểu thêm về toán tử sau.

Từ khóa

Từ khóa là các từ ưu tiên trong Ruby, thường dùng làm các câu lệnh thực hiện hành động nào đó, chẳng hạn như in giá trị ra màn hình, thực hiện các công việc lặp đi lặp lại hay thực hiện tính toán. Khi đặt tên biến chúng ta không được đặt tên trùng với từ khóa.

alias    and      BEGIN      begin    break    case
class    def      defined?   do       else     elsif
END      end      ensure     false    for      if
in       module   next       nil      not      or
redo     rescue   retry      return   self     super
then     true     undef      unless   until    when 
while    yield 

 

Ở trên là danh sách các từ khóa có trong Ruby.

Ruby – Giới thiệu về ngôn ngữ Ruby

Chào mừng bạn đến với bài mở đầu series lập trình với ngôn ngữ Ruby. Trong series này, bạn sẽ được học những thành phần chính của ngôn ngữ Ruby, bao gồm biến, biểu thức, tập hợp, luồng điều khiển, biểu thức chính quy và lập trình hướng đối tượng.

Ruby

Ruby logo

Ruby là một ngôn ngữ lập trình động, phản xạ, hướng đối tượng. Tác giả của ngôn ngữ Ruby là một lập trình viên người Nhật tên là Yukihiro Matsumoto. Ruby được giới thiệu lần đầu vào năm 1995.

Ruby hỗ trợ hầu hết các mô hình lập trình truyền thống, bao gồm lập trình hướng đối tượng, lập trình phản xạ, lập trình mệnh lệnh… Ruby được lấy cảm hứng từ Perl, Smalltalk, Effiel và Lisp.

Website chính thức của Ruby có địa chỉ ruby-lang.org.

Trình thông dịch Ruby

Trong series này mình dùng Ruby phiên bản 2.2.4 trên Windows. Bạn có thể tải và cài đặt Ruby cho Windows tại địa chỉ http://rubyinstaller.org/, Khi cài bạn nhớ check lựa chọn cho trình cài đặt tự động gán đường dẫn đến thư mục bin trong biến PATH luôn cho tiện.

Sau khi cài xong, bạn mở Command Prompt (cmd) lên và chạy lệnh irb để mở trình thông dịch Ruby, màn hình cùng với dấu nhắc lệnh của Ruby có dạng như sau:

C:\User\PhoCode> irb
irb(main):001:0> 

Từ đây bạn có thể gõ các lệnh trong Ruby.

irb(main):001:0> puts RUBY_VERSION 
2.2.4 => nil

Ở trên chúng ta chạy lệnh puts, lệnh này sẽ in một đoạn text ra màn hình, ở đây chúng ta in hằng số RUBY_VERSION, hằng số này cho biết phiên bản Ruby mà chúng ta sử dụng.

Viết code Ruby trong file

Ngoài cách chạy Ruby trực tiếp từ trình thông dịch thì chúng ta có thể viết code Ruby trong các file script riêng rồi trình thông dịch sẽ chạy đoạn code trong file đó. Bạn chỉ cần tạo một file text, viết code Ruby trong đó rồi lưu lại với phần mở rộng là .rb.

puts "Hello world"

Đoạn code trên sẽ in chuỗi Hello world ra màn hình.

C:\Project\Ruby>hello.rb 
Hello world

Để chạy file .rb thì bạn mở cmd lên rồi trỏ đến thư mục chứa file này (bằng lệnh cd) sau đó gõ vào tên file là xong.

Tài liệu tham khảo