inicio mail me! sindicaci;ón

Bàn thêm về Chuỗi (String)

Lớp String có nhiều phương thức, và bạn không phải nhớ hết tất cả các phương thức này (khi cần bạn có thể tra trong tài liệu tra cứu của Ruby). Một số ví dụ như hàm reverse trả lại chuỗi sau khi đã đảo ngược thứ tự của các kí tự (không thay đổi chuỗi gốc). Hàm length cho biết số kí tự (tính cả kí tự trống) trong chuỗi. upcase đổi chuỗi thành toàn bộ chữ hoa, downcase đổi chuỗi thành toàn bộ chữ thường. swapcase đổi từng kí tự thành thường/hoa nếu kí tự đó là hoa/thường., và capitalize có chức năng giống downcase trừ việc nó viết hoa kí tự đầu của chuỗi. Hàm slice cho ra chuỗi con của một chuỗi lớn hơn.

Các hàm upcase, downcase, swapcasecapitalize có những phương thức ra lệnh tương ứng: upcase!, downcase!, swapcase!capitalize!. Giả dụ bạn không cần dùng chuỗi gốc nữa, bạn có thể dùng phương thức ra lệnh để tiết kiệm bộ nhớ, đặc biệt khi chuỗi lớn.

Chuỗi nguyên (String Literals) là chuỗi gồm các kí tự nằm giữa hai dấu ngoặc nhỏ hoặc ngoặc kép. Điểm khác biệt của 2 loại dấu ngoặc này nằm ở cách Ruby xử lý chuỗi. Trong trường hợp bạn dùng ngoặc nhỏ để bao chuỗi, Ruby ít khi phải xử lý. Trong trường hợp bạn dùng ngoặc kép, Ruby phải xử lý nhiều hơn. Đầu tiên nó sẽ tìm trong chuỗi các kí tự thoát (dấu \ ) và thay dãy kí tự khác kí tự trống đi theo sau kí tự thoát bằng một giá trị nhị phân nào đó. Công việc thứ 2 mà Ruby xử lý đối với chuỗi có dấu ngoặc kép, là lồng ghép lệnh hoặc giá trị để thay thế chuỗi con #{expression} (xem ví dụ p013expint.rb dưới đây).

def say_goodnight (name)
  result = "Good night, #{name}"
  return result
end
puts say_goodnight('Satish')
#modified program
def say_goodnight2(name)
  "Good night, #{name}"
end
puts say_goodnight2('Talim')

Ta để ý thấy trong phương thức say_goodnight2, ta không cần dùng biến tạm result và lệnh return. Thay vì đó ta chỉ cần để giá trị chuỗi trả lại ở dòng cuối của khối khai báo phương thức. Giá trị này sẽ tự động được trả lại. Cũng cần chú ý rằng mỗi khi chuỗi nguyên được dùng trong câu lệnh gán, hoặc dùng làm tham số, một đối tượng String sẽ được tạo ra.

Chú thích của người dịch: Đoạn này tác giả diễn giải có vẻ khó hiểu. Nhưng thực ra không có gì cả. Như các bạn thấy, ta có thể gán chuỗi bằng 2 dòng mã sau:

str1 = 'test \t test'
str2 = "test \t test"
puts str1
puts str2

Bạn sẽ thấy chuỗi nằm giữa dấu ngoặc nhỏ sẽ không được Ruby xử lý thoát ký tự đặc biệt (\t là chuỗi thoát dùng cho kí tự tab), trong khi chuỗi nằm giữa dấu ngoặc kép thì có xử lý. Thử thêm ví dụ này để thấy sự khác biệt:

a = 123
str1 = 'test #{a} test'
str2 = "test #{a} test"
puts str1
puts str2

Bộ nhớ được quản lý ra sao đối với các chuỗi trong Ruby? Có giới hạn nào đối với chuỗi không?

Chuỗi là đối tượng của lớp String. Lớp String có hơn 75 phương thức chuẩn. Nếu bạn tham khảo trong Ruby User’s Guide, nó có nói “ta không cần quan tâm đến dung lượng bộ nhớ mà chuỗi chiếm. Ta hoàn toàn không phải quan tâm đến bất kì việc gì liên quan đến quản lý bộ nhớ”.

Liệt kê toàn bộ các phương thức của một lớp hoặc một đối tượng

String.methods.sort sẽ liệt kê cho bạn các phương thức lớp tác động lên lớp String (mà bản thân nó cũng là đối tượng của lớp Class)

String.instance_methods.sort liệt kê các phương thức đối tượng mà các đối tượng chuỗi có sẵn.

String.instance_methods(false).sort liệt kê các phương thức đối tượng của một đối tượng String, đã loại bỏ các phương thức được thừa hưởng từ lớp.

So sánh 2 chuỗi

Có vài cách để so sánh xem hai chuỗi có bằng nhau không. Cách thông thường nhất là dùng toán tử == (hai dấu bằng). Một cách nữa là dùng phương thức eql? để kiểm tra xem hai chuỗi có chứa giá trị như nhau không. Nó sẽ cho ra kết quả giống với ==. Phương thức thứ ba là equal?, kiểm tra xem hai chuỗi có phải cùng là một đối tượng không. Ví dụ sau đây sẽ minh họa cho điều này (p013strcmp.rb):


s1 = 'Jonathan'
s2 = 'Jonathan'
s3 = s1
if s1 == s2
  puts 'Both Strings have identical content'
else
  puts 'Both Strings do not have identical content'
end
if s1.eql?(s2)
  puts 'Both Strings have identical content'
else
  puts 'Both Strings do not have identical content'
end
if s1.equal?(s2)
  puts 'Two Strings are identical objects'
else
  puts 'Two Strings are not identical objects'
end
if s1.equal?(s3)
  puts 'Two Strings are identical objects'
else
  puts 'Two Strings are not identical objects'
end

Sử dụng %w

Đôi khi tạo mảng bao gồm các chuỗi từ sẽ rất mất công và phiền hà do có nhiều dấu ngoặc và phẩy. Rất may là trong Ruby có một cách làm tắt: %w.


names1 = [ 'ann', 'richard', 'william', 'susan', 'pat' ]
puts names1[0] # ann
puts names1[3] # susan
# this is the same:
names2 = %w{ ann richard william susan pat }
puts names2[0] # ann
puts names2[3] # susan

Thực hành:

Cho trước 1 chuỗi. Yêu cầu là đảo ngược thứ tự các từ của chuỗi đó. Bạn có thể dùng phương thức split để lấy một mảng lập bởi các từ của chuỗi. Lớp Array (mảng) có phương thức đảo ngược (reverse) và ghép nối các phần tử thành một chuỗi (join).

words = 'Learning Ruby - Your one stop guide'
puts words.split(" ").reverse.join(" ") # guide stop one Your - Ruby Learning

Xem thêm tài liệu đầy đủ về lớp String.

QAD said,

March 11, 2008 @ 12:44 pm

Tớ hỏi chút ngoài lề nhé: Cậu làm thế nào để giữ được indentation trong code thế? Có dùng WYSIWYG editor của WordPress không?

c40 said,

March 11, 2008 @ 1:02 pm

Tớ dùng WYSIWYG của WP, nhưng mà tớ paste thẳng sourcecode từ IDE vào.
Tất nhiên lúc mới publish thì indentation vẫn ok, nhưng mà vào edit 1 phát và save lại là y như rằng mất hết, lại phải lọ mọ vào chỉnh sửa lại.
Nói chung tớ không thạo WP nên cũng chưa tìm ra cách gì giải quyết vấn đề này :D

QAD said,

March 12, 2008 @ 2:06 am

À ừ, edit sẽ bị lại.

Thực ra có 2 cách để xử lý:

Một là tắt hoàn toàn WYSIWYG, dùng raw HTML editor.

Hai là vẫn dùng WYSIWYG, wrap tất cả trong thẻ , khi ấy plugin sẽ cho một cái nested pre nữa, hơi lởm chút nhưng được cái ko bị lỗi edit nữa.

RSS feed for comments on this post · TrackBack URI

Leave a Comment