Lịch sử hình thành: Nguồn : http://vi.wikipedia.org Ruby là một ngôn ngữ lập trình hướng đối tượng, có khả năng reflection.. Cú pháp bị ảnh hưởng từ Ada và Perl với các đặc tính hướng đố
Trang 1- -BÀI TẬP LỚN MÔN : NGUYÊN LÝ CÁC NGÔN NGỮ LẬP TRÌNH
Đề số 10 : Tìm hiểu ngôn ngữ lập trình Ruby
Nhóm : Nhóm 12 Thành viên : Ngô Hoàng Thành (Nhóm trưởng)
Luyện Thanh Tuấn Trần Hữu Thảo
Lớp : Cao học 12BCNTT2
Hà Nội, 12 - 2012
Trang 2Mục lục
1 Tổng quan về ngôn ngữ lập trình Ruby 2
1.1 Lịch sử hình thành: 2
1.2 Giới thiệu về Ruby : 2
1.3 Tính hướng đối tượng của Ruby 3
1.4 Tính mềm dẻo của Ruby 3
2 Các thành phần của Ruby 4
2.1 Biến trong ruby 4
2.2 Các dạng dữ liệu trong ruby 4
2.2.1 Number 4
2.2.2 String 4
2.3 Array 5
2.4 Cấu trúc điều khiển trong ruby 6
2.5 Vòng lặp trong ruby 7
2.5.1 Vòng lặp while 7
2.5.2 Vòng lặp until 7
2.5.3. Vòng lặp for : 8
2.5.4 Mảng Hash : 8
2.6 Class trong Ruby 8
2.6.1 Khai báo class, method : 8
2.6.2 Khởi tạo class 9
2.6.3 Hàm khởi tạo của class 9
2.7 Kế thừa trong Ruby 9
2.7.1 Cú pháp khai báo 9
2.7.2 Đa kế thừa 9
3 BNF của Ruby 11
Trang 31 Tổng quan về ngôn ngữ lập trình Ruby
1.1 Lịch sử hình thành:
(Nguồn : http://vi.wikipedia.org)
Ruby là một ngôn ngữ lập trình hướng đối tượng, có khả năng reflection Cú pháp bị ảnh hưởng từ Ada và Perl với các đặc tính hướng đối tượng của Smalltalk, và cũng chia
sẻ một số đặc tính với Python, Lisp, Dylan và CLU Ruby là ngôn ngữ thông dịch đơn giai đoạn
Ruby được tạo ra bởi Yukihiro “Matz” Matsumoto từ 24 tháng 2, 1993 và đưa ra bản chính thức vào năm 1995
Tháng 9 năm 2005, phiên bản ổn định mới nhất là 1.8.3
Ruby 1.9 (với một số thay đổi) cũng đang trong quá trình phát triển
Phiên bản ổn địn mới nhất là 1.9.2 Ruby 1.9 có nhiều thay đổi đáng kể so với dòng 1.8 Ví như:
Biến cục bộ trong khối lệnh
Thêm cú pháp khai báo hàm nặc danh (fun = ->(a,b) { puts a + b })
Chọn kiểu mã hóa ký tự cho từng chuỗi
Socket API mới (hỗ trợ IPv6)
1.2 Giới thiệu về Ruby :
Theo lời giới thiệu về Ruby của cộng đồng Ruby thì: “Ruby là một ngôn lập trình
mã nguồn mở, linh hoạt, với một sự nổi bật về sự đơn giản dễ dùng và hữu ích Nó có
cú pháp “tao nhã” và tự nhiên dễ đọc và dễ dàng để viết”
Ruby chịu nhiều ảnh hưởng của Perl, Smalltalk, Eiffel, Ada, và Lisp do tác giả của Ruby – Matz – thích các ngôn ngữ này Do đó các câu lênh và cú pháp của Ruby khá tương đồng với các ngôn ngữ này
Đặc điểm cơ bàn dễ nhận thấy ở Ruby là :
Ruby có cú pháp ngắn nhưng có thể làm được nhiều việc
Ruby là ngôn ngữ rất hướng đối tượng
Trang 41.3 Tính hướng đối tượng của Ruby
Với Ruby, mọi thứ đều là một đối tượng Mọi bit thông tin hay code đều có thể
sở hữu các thuộc tính hay phương thức Ruby là một ngôn ngữ hướng đối tượng “tinh khiết”, điều này có thể thấy bằng việc một số cũng có phương thức của mình
Ví dụ : số 5 cũng được coi là một đối tượng và có phương thức times.
Đoạn code dưới sẽ in ra 5 lần dòng “We *love* Ruby”:
5.times{ print "We *love* Ruby" }
Đa số các ngôn ngữ khác, con số và một số kiểu dữ liệu nguyên thủy khác thì không được coi là hướng đối tượng Nhưng Ruby theo sự ảnh hưởng lớn của ngôn ngữ Smalltalk bằng việc đưa ra các phương thức và thực thể biến tới tất cả các kiểu của nó Điều này tạo nên sự thống nhất và dế dàng khi sử dụng Ruby với tất cả các đối tượng
1.4 Tính mềm dẻo của Ruby
Ruby được coi là một ngôn ngữ mềm dẻo và linh hoạt, từ khi nó cho phép người dùng tự do sửa đổi cả phần cốt lõi của nó Các phần cốt lõi của Ruby có thể được rời đi hoặc định nghĩa lại như ý muốn Các phần hiện hữu có thể được thêm vào Ruby cố gắng không hạn chế các nhà lập trình
Trang 52 Các thành phần của Ruby
2.1 Biến trong ruby
Biến của ruby không cần khai báo kiểu Khi gán giá trị cho biến nó sẽ tự động nhận kiểu, nhận các giá trị cho biến
Ví dụ:
User =”user”
Puts user => user Khai báo biến của ruby làm cho ngôn ngữ trở lên linh hoạt hơn
Biến toàn cục của ruby: khi thêm @ trước biến thì nó trở thành biến toàn cục để
sử dụng khi tác động trong chương trình Còn khi không có @ thì nó là biến địa phương chỉ được sử dụng trong một phần nào đó của chương trình
Mỗi biến của ruby là một đối tượng Nhờ vào vấn đề này, bạn có thể tác động đến từng vấn đề của biến như : chuyển kiểu, ghép các biến với nhau Nhờ có tính chất trên các biến trong ruby có thể tương tác với nhau một cách dễ dàng
Ví dụ:
@u =”Ngon ngu”
“{#@u} lap trinh”=> “Ngon ngu lap trinh”
2.2 Các dạng dữ liệu trong ruby
Ruby là một ngôn ngữ hướng đối tượng Ở đây các thành phần dữ liệu từ số, ký
tự, mảng đều được xây dựng trên cơ sở các class
2.2.1 Number
Cấu trúc phân cấp dữ liệu dạng số trong Ruby: Các dang dữ liệu kiểu số được xây dựng từ lớp Numeric Kiểu số nguyên: Integer có hai dạng là Fixnum với độ dài 31 bits và Bignum có độ dài tùy ý Kiểu số thực được thể hiện qua lớp Float Bên cạnh đó một số kiểu dữ liệu khác không có sẵn nhưng được đinh nghĩa trong thư viện chuẩn của Ruby
Trang 62.2.2 String
String là lớp dùng để thể hiện chuỗi ký tự Khác với Java String trong Ruby là
“mutable” String trong Ruby có thể được khai báo trong dấu ngoặc đơn hoặc ngoặc kép Với dạng chuỗi được đặt trong dấu nháy đơn ‘’ thì ký tự \ chỉ có ý nghĩa khi sau nó
là ký tự \ hoặc ‘ Bên cạnh đó chuỗi trong nháy đơn được viết xuống dòng thì nó sẽ được hiển thị thành nhiều dòng tương ứng Với dạng chuối trong dấu nháy kép “” thì nhiều ký tự đặc biệt được hỗ trợ, ví dụ như \n, \t như trong java Bên cạnh đó chuối trong dấu nháy kép còn có thể hiện thị kết quả của biểu thức trong nó thông qua ký tự #
2.3 Array
Mảng có thể khai báo trực tiến hoặc thông qua đối tượng Array
Ví dụ:
Arr= [1,2,3,4,5,6]
Arr= Array.new Cách đánh chỉ số mảng trong Ruby được đánh từ 0 đến số phần tử -1
Ruby việc sắp xếp các thành phần mảng khá linh hoạt và mềm dẻo Ta có thể khai báo mảng một chiều gồm các phần tử đơn: arr = [1,2,3,4,5,6] Hoặc mảng lồng: arr
= [[1,2],[3,4,5,6],[7,8,9]] Hoặc mảng được trích xuất subArr = arr[0,2]#subArr = [[1,2], [3,4,5,6]]
Các mảng có thể tương tác với nhau thông qua các toán tử như +,-,*…
Với phép + ta có thể cộng hai mảng với nhau:
ar= [1,2,3] +[4] # ar=[1,2,3,4]
Với phép trừ các phần tử mảng ở mảng trừ sẽ loại bỏ các phần tử có trong mảng bị trừ:
ar= [1,2,3] -[2] # ar=[1,3]
Với phép nhân, ta có thể nhân một mảng với một số và kết quả cho ta số phần tử mảng được lặp lại theo giá trị được nhân:
ar= [1,2,3]*2 # ar= [1,2,3,1,2,3]
Các mảng có thể đính thêm phần tử với phép toán <<:
Trang 7ar= [1,2,3]<<4 # ar= [1,2,3,4].
Các phép so sánh: |, & Với | các giá trị trùng lặp của hai mảng sẽ được bỏ
đi ( kể cả các phần tử trùng lặp trong 1 mảng: ar = [1,2,2,4,3,4] | [] # ar[1,2,4,3] Trong khi đó với phép toán & các phần tử trùng nhau được giữ lại ( và không lặp): ar = [1,2,2,4,3,4] & [4,4] # ar[4]
2.4 Cấu trúc điều khiển trong ruby
Cấu trúc lệnh if :
if <<điều kiện>>
Các lệnh end
Cấu trúc if-else :
if <<điều kiện>>
Các lệnh else
Các lệnh end
Cấu trúc if-else if- else :
if <<điều kiện>>
Các lệnh elsif<<điều kiện>>
Các lệnh elsif<<điều kiện>>
Các lệnh end
Cấu trúc unless:
unless <<điều kiện>>
Các lệnh [else
Các lệnh]
Trang 8 Cấu trúc case:
Thay vì sử dụng switch và yêu cầu cần có break tại mỗi case như Java, Ruby sử
dụng cú pháp case – when – then :
case
when <>
then < >
when <>
then <>
when <>
then <>
end
2.5 Vòng lặp trong ruby
2.5.1 Vòng lặp while
Vòng lặp while – do
while <<điều kiện>> [do]
Các lệnh
end
Vòng lặp do – while :
begin
Các lệnh end while <<điều kiện>>
2.5.2 Vòng lặp until
Vòng lặp until – do :
until <<điều kiện>> [do]
Trang 9Các lệnh
end
Vòng lặp do – until
begin
Các lệnh end until <<điều kiện>>
2.5.3 Vòng lặp for :
for <<variables>> in <<collection>> do
Các lệnh end
2.5.4 Mảng Hash :
Mảng Hash là một dạng mở rộng của Array Array chỉ chấp nhận các chỉ số (index) là dạng số (Integer) thì mảng Hash chấp nhận chỉ số là một object bất kỳ Mảng
Hash không sử dụng chỉ số (index) để truy vấn dữ liệu mà sử dụng từ khóa (clef) để liên
kết với dữ liệu liên quan Ví dụ :
persons = {
"ten"=>"Nguyen Van A",
"nghe nghiep"=>"Sinh vien",
"lop"=>"12BCNTT2"
}
persons[ten] = "Nguyen Van A"
persons.each do |clef,value|
puts clef + "=>" + value end
ta sẽ in ra được các thuộc tính của persions
Trang 102.6 Class trong Ruby
2.6.1 Khai báo class, method :
class <<name_of_class>>
@@<<attribute_name>>
def <<method_name>>(params)
<<body of method>>
end end
2.6.2 Khởi tạo class
instance = <<name_of_class>>.new
2.6.3 Hàm khởi tạo của class
def initialize(<<variables>>)
<<khới tạo các giá trị>>
end
2.7 Kế thừa trong Ruby
2.7.1 Cú pháp khai báo
class Child_Class < ParentClass
<<Class body>>
End
2.7.2 Đa kế thừa
Ruby không hỗ trợ đa kế thừa nhưng ta có thể đưa các phương thức của module
khác nhau vào một lớp dẫn xuất dưới dạng Mixins (sử dụng include, require).
Ví dụ :
module A
def a1 end
Trang 11def a2 end end
module B
def b1 end def b2 end end
class Sample
include A include B def s1 end
end
samp=Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1
class Sample có đầy đủ phương thức của module A và B
Trang 123 BNF của Ruby
(Dựa trên http://docs.huihoo.com/ruby/ruby-man-1.4/yacc.html với một số thay đổi) PROGRAM : COMPSTMT
T : ";" | "\n" //a newline can terminate a statement
COMPSTMT : STMT {T EXPR} [T]
STMT : CALL do ["|" [BLOCK_VAR] "|"] COMPSTMT end
| undef FNAME
| alias FNAME FNAME
| STMT if EXPR
| STMT while EXPR
| STMT unless EXPR
| STMT until EXPR
| "BEGIN" "{" COMPSTMT "}" //object initializer
| "END" "{" COMPSTMT "}" //object finalizer
| LHS = COMMAND [do ["|" [BLOCK_VAR] "|"] COMPSTMT end]
| EXPR EXPR : MLHS = MRHS
| return CALL_ARGS
| yield CALL_ARGS
| EXPR and EXPR
| EXPR or EXPR
| not EXPR
| COMMAND
| ! COMMAND
| ARG
| COMMAND COMMAND : OPERATION CALL_ARGS
| PRIMARY.OPERATION CALL_ARGS
| PRIMARY :: OPERATION CALL_ARGS
| super CALL_ARGS
Trang 13FUNCTION : OPERATION ["(" [CALL_ARGS] ")"]
| PRIMARY.OPERATION "(" [CALL_ARGS] ")"
| PRIMARY :: OPERATION "(" [CALL_ARGS] ")"
| PRIMARY.OPERATION
| PRIMARY :: OPERATION
| super "(" [CALL_ARGS] ")"
| super
| for BLOCK_VAR in EXPR DO
COMPSTMT end
| begin
COMPSTMT {rescue [ARGS] DO COMPSTMT}
[else COMPSTMT]
[ensure COMPSTMT]
end
| class IDENTIFIER [< IDENTIFIER]
COMPSTMT end
| module IDENTIFIER
COMPSTMT end
| def FNAME ARGDECL
COMPSTMT end
| def SINGLETON ( | ::) FNAME ARGDECL
COMPSTMT end
WHEN_ARGS : ARGS [, * ARG] | * ARG
THEN : T | then | T then //"then" and "do" can go on next line
DO : T | do | T do
BLOCK_VAR : LHS | MLHS
Trang 14MLHS : MLHS_ITEM , [MLHS_ITEM (, MLHS_ITEM)*] [* [LHS]]
| * LHS MLHS_ITEM : LHS | "(" MLHS ")"
| PRIMARY "[" [ARGS] "]"
| PRIMARY.IDENTIFIER MRHS : ARGS [, * ARG] | * ARG
CALL_ARGS : ARGS
| ARGS [, ASSOCS] [, * ARG] [, & ARG]
| ASSOCS [, * ARG] [, & ARG]
| * ARG [, & ARG] | & ARG
| COMMAND ARGS : ARG (, ARG)*
| LHS OP_ASGN ARG
| ARG ARG | ARG ARG
| ARG + ARG | ARG - ARG | ARG * ARG | ARG / ARG
| ARG % ARG | ARG ** ARG
| + ARG | - ARG
| ARG "|" ARG
| ARG ˆ ARG | ARG & ARG
| ARG <=> ARG
| ARG > ARG | ARG >= ARG | ARG < ARG | ARG <= ARG
| ARG == ARG | ARG === ARG | ARG != ARG
| ARG =˜ ARG | ARG !˜ ARG
| ! ARG | ˜ ARG
| ARG << ARG | ARG >> ARG
| ARG && ARG | ARG || ARG
| defined? ARG
| PRIMARY PRIMARY : "(" COMPSTMT ")"
| LITERAL
| VARIABLE
Trang 15| PRIMARY :: IDENTIFIER
| :: IDENTIFIER
| PRIMARY "[" [ARGS] "]"
| "[" [ARGS [,]] "]"
| "{" [ARGS | ASSOCS [,]] "}"
| return ["(" [CALL_ARGS] ")"]
| yield ["(" [CALL_ARGS] ")"]
| defined? "(" ARG ")"
| FUNCTION
| FUNCTION "{" ["|" [BLOCK_VAR] "|"] COMPSTMT "}"
| if EXPR THEN
COMPSTMT {elsif EXPR THEN COMPSTMT}
[else COMPSTMT]
end
| unless EXPR THEN
COMPSTMT [else
COMPSTMT]
end
| while EXPR DO COMPSTMT end
| until EXPR DO COMPSTMT end
| case COMPSTMT
when WHEN_ARGS THEN COMPSTMT {when WHEN_ARGS THEN COMPSTMT}
[else COMPSTMT]
end ARGDECL : "(" ARGLIST ")"
| ARGLIST T ARGLIST : IDENTIFIER(,IDENTIFIER)*[, *[IDENTIFIER]][,&IDENTIFIER]
| *IDENTIFIER[, &IDENTIFIER]
| [&IDENTIFIER]
Trang 16SINGLETON : VARIABLE
| "(" EXPR ")"
ASSOCS : ASSOC {, ASSOC}
ASSOC : ARG => ARG
VARIABLE : VARNAME | nil | self
LITERAL : numeric | SYMBOL | STRING | STRING2 | HERE_DOC | REGEXP OP_ASGN : += | -= | *= | /= | %= | **=
| &= | |= | ˆ= | <<= | >>=
| &&= | ||=
SYMBOL : :FNAME | :VARNAME
FNAME : IDENTIFIER | | "|" | ˆ | & | <=> | == | === | =˜
| > | >= | < | <= | + | - | * | / | % | **
| << | >> | ˜ | +@ | -@ | [] | []=
OPERATION : IDENTIFIER [! | ?]
VARNAME : GLOBAL | @IDENTIFIER | IDENTIFIER
GLOBAL : $IDENTIFIER | $any_char | $-any_char
STRING : " {any_char} "
| ’ {any_char} ’
| ‘ {any_char} ‘ STRING2 : %(Q|q|x)char {any_char} char
HERE_DOC : <<(IDENTIFIER | STRING)
{any_char}
IDENTIFIER REGEXP : / {any_char} / [i|o|p]
| %r char {any_char} char IDENTIFIER : sequence in /[a-zA-Z_]{a-zA-Z0-9_}/