Content | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11

Official Ruby FAQ

If you wish to report errors or suggest improvements for this FAQ, please go to our GitHub repository and open an issue or pull request.

Các tính năng khác

a ? b : c có nghĩa là gì?

Đây là cái gọi là “toán tử ba ngôi” và tương đương với if a then b else c end.

Làm thế nào để đếm số dòng trong một tệp?

Đoạn mã sau có thể cho kết quả nhanh nhất.

File.readlines("example").size  # => 3

MatchData#beginMatchData#end trả về gì?

Chúng hoạt động với $~, và trả về chỉ mục bắt đầu và chỉ mục kết thúc của dữ liệu khớp trong chuỗi gốc. Xem ví dụ trong mở rộng tab.

Làm thế nào để tính tổng các phần tử trong một mảng?

This section or parts of it might be out-dated or in need of confirmation.

Thay vì giải quyết bài toán cụ thể, hãy giải quyết trường hợp tổng quát. Điều đầu tiên chúng ta sẽ làm là tạo một phương thức duyệt qua một đối tượng Enumerable và thu thập một kết quả duy nhất. Smalltalk gọi phương thức đó là inject, nên chúng ta cũng sẽ gọi như vậy:

module Enumerable

  # inject(n) {|n, i| ...}
  def inject(n)
    each {|i| n = yield(n, i) }

    n
  end
end

Lưu ý cách chúng ta thêm phương thức vào Enumerable. Điều này có nghĩa là bất cứ thứ gì include Enumerable giờ đều có thể sử dụng inject. Nhưng làm thế nào để sử dụng nó? Nó nhận một đối số duy nhất n và một block. Với mỗi phần tử trong đối tượng đang được duyệt, nó gọi block, truyền vào n và chính phần tử đó. Kết quả của block được gán lại cho n. Vì vậy, để định nghĩa sum, chúng ta có thể viết:

module Enumerable
  def sum
    inject(0) {|n, i| n + i }
  end
end

[1,3,5,7,9].sum  # => 25
(1..100).sum     # => 5050

Làm thế nào để sử dụng continuation?

This section or parts of it might be out-dated or in need of confirmation.

Continuation trong Ruby cho phép bạn tạo một đối tượng đại diện cho một vị trí trong chương trình Ruby, và sau đó quay lại vị trí đó bất cứ lúc nào (ngay cả khi nó dường như đã ra khỏi phạm vi). Continuation có thể được sử dụng để triển khai các cấu trúc điều khiển phức tạp, nhưng thường hữu ích hơn như một cách để làm rối người khác.

Trong [ruby-talk:4482], Jim Weirich đã đăng các ví dụ sau về continuation:

# --------------------------------------------------------------------
# Simple Producer/Consumer
# --------------------------------------------------------------------
# Connect a simple counting task and a printing task together using
# continuations.
#
# Usage:  count(limit)

def count_task(count, consumer)
  (1..count).each do |i|
    callcc {|cc| consumer.call cc, i }
  end
  nil
end

def print_task()
  producer, i = callcc { |cc| return cc }
  print "#{i} "
  callcc { |cc| producer.call }
end

def count(limit)
  count_task(limit, print_task())
  print "\n"
end
# --------------------------------------------------------------------
# Filtering Out Multiples of a Given Number
# --------------------------------------------------------------------
# Create a filter that is both a consumer and producer. Insert it
# between the counting task and the printing task.
#
# Usage:  omit(2, limit)

def filter_task(factor, consumer)
  producer, i = callcc { |cc| return cc }
  if (i%factor) != 0 then
    callcc { |cc| consumer.call cc, i }
  end
  producer.call
end

def omit(factor, limit)
  printer = print_task()
  filter = filter_task(factor, printer)
  count_task(limit, filter)
  print "\n"
end
# --------------------------------------------------------------------
# Prime Number Generator
# --------------------------------------------------------------------
# Create a prime number generator. When a new prime number is
# discovered, dynamically add a new multiple filter to the chain of
# producers and consumers.
#
# Usage:  primes(limit)

def prime_task(consumer)
  producer, i = callcc { |cc| return cc }
  if i >= 2 then
    callcc { |cc| consumer.call cc, i }
    consumer = filter_task(i, consumer)
  end
  producer.call
end

def primes(limit)
  printer = print_task()
  primes = prime_task(printer)
  count_task(limit, primes)
  print "\n"
end