12/08/2018, 15:01

Khái niệm cơ bản về array và block trong ruby

A whole lot of programming deals with lists of things Hầu hết các ngôn ngữ lập trình đều có cấu trúc dữ liệu dạng mảng các các đối tượng, các số, các từ, các sản phẩm... Ruby cũng không phải ngoại lệ, Matz người viết ra ngôn ngữ ruby biết điều đón nên ông ấy đã làm việc một cách chăm chỉ để đảm ...

A whole lot of programming deals with lists of things

Hầu hết các ngôn ngữ lập trình đều có cấu trúc dữ liệu dạng mảng các các đối tượng, các số, các từ, các sản phẩm... Ruby cũng không phải ngoại lệ, Matz người viết ra ngôn ngữ ruby biết điều đón nên ông ấy đã làm việc một cách chăm chỉ để đảm bảo không chỉ có như các ngôn ngữ mà còn phải dễ sử dụng. Đầu tiên ông ấy cũng đảm bảo rằng các phương thức hỗ trợ đi kèm thực sự linh hoạt và hiệu quả .

Thứ hai, ông ấy nhận ra rằng viết code để duyệt qua từng đối tượng trong arrays đó thật sự là tẻ nhạt và buồn chán, khiến cho code khó bảo trì, thiếu linh hoạt và tốn công code của các lập trình viên. Vì vậy ông ấy đã thêm một khái niệm block trong ruby để loại bỏ sử thiếu linh hoạt và nhàm chán đó. Vậy block là gì? bài viết dưới đây sẽ giải thích cho bạn.

Arrays

Array được sử dụng để lưu trữ tập hợp các đối tượng với chiều dài của array là bao nhiêu tùy ý. Để tạo một array trong ruby có thể sử dụng các cách sau:

array = Array.new

Hoặc tạo luôn một array chứa các đối tượng cho trước

array = [2.99,  25.00,  9.99]

Để lấy giá trị trong array có thể sử dụng khái niệm index để chỉ ra vị trí mà mình muốn đọc dữ liệu trong mạng chỉ định .Ví dụ

puts array[0]   #2.99
puts array[2]   #25.0
puts array[1]   #9.99
  • array cũng là một object vậy. Array cũng được hỗ trọ các phương thức rất linh hoạt để sử dụng
prices = [7.99, 25.00, 3.99, 9.99]
puts prices.class      #Array

Một số phươn thức hay được sử dụng trong ruby

  • Thay vì sử dụng index để lấy có thể sự các phương thức first, last để đọc các phần tử đầu tiên hoặc cuối cùng trong dãy
puts prices.first  #7.99
puts prices.last   #9.99
  • Phương thức để kiểm tra sự tồn tại của các đối tượng có trong array
puts prices.include?(25.00)   #true
puts prices.find_index(9.99)  #3
  • Các phương thức để thêm hoặc bớt phần tử trong array
prices.push(0.99)
p prices :[7.99, 25.0, 3.99, 9.99, 0.99]
prices.pop
p prices :[7.99, 25.0, 3.99, 9.99]
prices.shift
p prices :[25.0, 3.99, 9.99]
prices << 5.99
prices << 8.99
p prices :[25.0, 3.99, 9.99, 5.99, 8.99]
  • Phương thức để join các phần tử trong array lại với nhau.
puts ["d", "o", "g"].join #dog
puts ["d", "o", "g"].join("-")  #d-o-g

Blocks

Như đã giới thiệu ở đầu bài viết block là một khái niệm khó trong ruby nhưng và chắc chắn bạn sẽ không nhìn thấy cấu trúc như này trước đây. Nhưng nếu lắm được nó, block sẽ giúp bạn rất nhiều. Hãy tưởng tượng có một ai đó(block) đã giúp bạn xử lý phần đầu cuối nhàm chán hay chính xác là việc duyệt dữ liệu công việc của bạn bây giờ là viết các đoạn code thông minh hay các đoạn code xử lý nghiệp vụ. Bạn có sẵn sàng để sử dụng nó hãy kiên nhẫn, nhâm nhi 1 cốc cafe để tỉnh táo hơn và bắt đầu làm quen với block. Let's get to it!

Your first block
my_method do
  puts "We're in the block!"
end

Một số lưu ý

  1. Bắt đầu một block được đánh dấu bới keyword do và kết thúc được đánh dấu bới keyword end
  2. Trong block có thể chứ 1 hoặc nhiều hơn 1 dòng code
  3. Khi block được gọi thì có nghĩa là nội dung trong block cũng được gọi để thực thi Ví dụ
def my_method(&my_block)
  puts "We're in the method, about to invoke your block!"
  my_block.call
  puts "We're back in the method!"
end

my_method do
  puts "We're in the block!"
end

Kết quả

We're in the method, about to invoke your block!
We're in the block!
We're back in the method!

Block parameters Tượng tự việc truyền các tham số vào trong các phương thức của ruby, việc truyền các các tham số vào các block cũng vậy các tham trị sẽ được truyền và sủ dụng các giá trị đó trong block ví dụ

def give(&my_block)
  my_block.call("2 turtle doves", "1 partridge")
end

give do |present1, present2|
  puts "My method gave to me..."
  puts present1, present2
end

Sự dụng từ khóa yield để thay thế cho việc sử dụng phương thức call

def twice(&my_block)
  my_block.call
  my_block.call
end

Định dạng của block Ngoài sử dụng các từ khóa do, end để định nghĩa một block còn có một cách khác là sử dụng dấu {} để định nghĩa với 2 kiểu đều có thể nhìn thấy ở các đoạn code bên ngoài. Còn các mình sử dụng hai định dạng như sau đối với một block chỉ có một đoạn code ngắn sẽ sử dụng dấu {}, còn đối với block có từ 2 dòng code trở lên hoặc phức tạp sẽ sử dụng do end để biểu diễn.

def take_this
  yield "present"
end

take_this do |thing|
  puts "do/end block got #{thing}"
end

take_this {|thing| puts "brackets block got #{thing}"}

The "each" method Ở phía trên mình đã giới thiệu về cách sử dụng block cũng như các định dạng có thể, các truyền các tham số trong block . Và bây giờ là thời điểm thích hợp có thể giải quyết bài toán mình nêu ra ở trên bằng một phương thức của Ruby đó là "each". Phương thức each sẽ duyệt các từng phần tử của mảng, yielding các phần tử đó và block và chạy các đoạn code logic. Ví dụ:

["a", "b", "c"].each { |param| puts param }  #a b c

Trong có vẻ đoạn code đã được rút ngắn và tối ưu hơn rất nhiều so với đoạn code dưới đây

def each
  index = 0
  while index < self.length
    // do something
    index += 1
  end
end

For example:

prices = [3.99, 25.00, 8.99]
prices.each {|price| amount += price}
puts format("%.2f", total(prices))  #37.98

Perfect! Hay phải không tiếp theo mình cũng muốn giới thiệu một phương thức cũng rất hay được sử dụng trong quá trình lập trình với ngôn ngữ ruby này Map Map cũng tượng tự each tuy nhiên map khac với block một điểm là map sẽ trả kết quả về sau khi đã thực hiện xử lý logic trong block đó(object sử dụng map sẽ vẫn được giữ nguyên trừ khi sử dụng map!). Ví dụ

[1, 2, 3].map { |n| n * n }  #=> [1, 4, 9]

Ngoài each và map mình giới thiệu ở trên còn có rất nhiều các phương thức khác sử dụng kĩ thuật block trong ruby các bạn có thể lên google và tìm hiểu rõ hơn về các phương thức đó. Mình sẽ liệt kê một số phương thức : collect, select, each_with_index(sử dụng trong trường hợp duyệt mảng và lấy ra các index của mảng đó)... Để có thể hiểu rõ hơn và tìm kiểm các phương thức các bạn mong muốn mình đình kèm đường dẫn bên dưới là thư viện về Array của phiên bản ruby 2.2.0 https://ruby-doc.org/core-2.2.0/Array.html

Cảm ơn các bạn đã đọc bài viết của mình , nếu cảm thấy thắc mắc hoặc sai sót bạn có thể comment bên dưới để trao đổi, Have a nice day!

0