2013-09-03 20 views
6

Mã sau đây đang sử dụng toán tử flip-flop.Tại sao toán tử Flip-Flop lại bao gồm điều kiện thứ hai?

(1..10).each {|x| print "#{x}," if x==3..x==5 } 

Tại sao kết quả là 3,4,5?

Tôi nghĩ rằng nó phải là 3,4.

Như đã đề cập trong hướng dẫn, biểu thức này trở thành true khi x == 3 và tiếp tục đúng cho đến x == 5. Làm thế nào có thể '5' được in nếu nó đánh giá sai? Bất cứ ai có thể vui lòng làm rõ điều đó cho tôi?

+0

liên kết tài liệu, vui lòng .. –

+3

Bạn đã trả lời câu hỏi của riêng mình. 'và tiếp tục đúng cho đến khi x == 5' – MurifoX

+0

nhưng khi x trở thành 5, nó là sai phải không? làm thế nào có thể 5 được in sau đó? – bean

Trả lời

0

Bạn đang tìm kiếm một phạm vi độc quyền? Bạn có thể sử dụng ba dấu chấm và phương thức cover?.

(1..10).each { |x| print "#{x}," if (3...5).cover?(x) } 

Lý do nó in 3,4,5, trong ví dụ của bạn là vì nó nói nếu x nằm trong khoảng từ 3 đến 5 in.

0

Để làm rõ nhận xét của @MurifoX, Flip-flop là đúng cho đến x==5, và do đó thực sự cụ thể khi x==5, nhưng là sai mỗi khi biểu thức được đánh giá sau đó. Vì vậy, bạn vẫn thấy 5 đang được in.

+0

cảm ơn, điều đó là hợp lý. – bean

4

Các mắt xích quan trọng, từ "The Ruby Ngôn ngữ lập trình" là:

4.6.9.1 Boolean flip-flops

Khi .. và ... khai thác được sử dụng trong một điều kiện, chẳng hạn như một câu lệnh if, hoặc trong một vòng lặp, chẳng hạn như vòng lặp while (xem Chương 5 để biết thêm về điều kiện và vòng lặp), chúng không tạo đối tượng Phạm vi. Thay vào đó, họ tạo ra một loại biểu thức Boolean đặc biệt gọi là flip-flop. Biểu thức flip-flop đánh giá đúng hoặc sai, giống như biểu thức so sánh và bình đẳng . Tuy nhiên, điều đặc biệt bất thường về một biểu thức flip-flop là giá trị của nó phụ thuộc vào giá trị của các đánh giá trước đó là . Điều này có nghĩa là một biểu thức flip-flop có trạng thái kết hợp với nó; nó phải nhớ thông tin về các đánh giá trước đó. Bởi vì nó có nhà nước, bạn sẽ mong đợi một flip-flop là một đối tượng của một số loại. Nhưng không phải — đó là biểu thức Ruby, và trình thông dịch Ruby lưu trữ trạng thái (chỉ một giá trị Boolean đơn) mà nó yêu cầu trong biểu diễn phân tích nội bộ của biểu thức.

Với ý tưởng đó, hãy xem xét flip-flop trong đoạn mã sau. Lưu ý rằng đầu tiên .. trong mã tạo đối tượng Phạm vi. Điều thứ hai tạo ra các flip-flop biểu:

(1..10).each {|x| print x if x==3..x==5 } 

các flip-flop gồm hai biểu thức Boolean tham gia với các nhà điều hành .., trong bối cảnh của một điều kiện hoặc vòng lặp. Biểu thức flip-flop là sai trừ khi và cho đến khi biểu thức thứ tự ước tính là đúng. Một khi biểu thức đó đã trở thành sự thật, thì giả thuyết ex- "lật" vào trạng thái thực sự liên tục. Nó vẫn còn trong trạng thái đó, và các đánh giá tiếp theo trả về true cho đến khi biểu thức đúng đánh giá là đúng.Khi đó xảy ra, flip-flop "flops" trở lại trạng thái sai liên tục. Các đánh giá tiếp theo của biểu thức trả về false cho đến khi biểu thức lefthand trở thành true một lần nữa. Trong ví dụ mã, flip-flop được đánh giá nhiều lần, cho các giá trị của x từ 1 đến 10. Nó bắt đầu ở trạng thái sai, và đánh giá sai khi x là 1 và 2. Khi x == 3, flip-flop flips thành true và trả về true. Nó tiếp tục trở lại đúng khi x là 4 và 5. Khi x == 5, tuy nhiên, flip-flop flops trở lại false, và trả về false cho các giá trị còn lại của x. Kết quả là mã này in 345.

3

.. hoặc flip-flop được kế thừa từ Perl lấy từ AWK và sed trong * nix. Nó rất mạnh mẽ, nhưng trong sử dụng cụ thể của bạn nó khá mơ hồ và không phải là một lựa chọn tốt cho logic bạn muốn, đặc biệt là trong Ruby. Thay vì sử dụng:

(1..10).each {|x| puts x if (3..5) === x } 

Những kết quả đầu ra:

3 
4 
5 

Điều đó nói rằng, nó là vô cùng mạnh mẽ khi bạn cần để trích xuất một loạt các dòng từ một tập tin:

File.foreach('/usr/share/dict/propernames') { |li| puts li if ($. == 5 .. $. == 7) } 

Những kết quả đầu ra:

Agatha 
Ahmed 
Ahmet 

Pe rl cho phép một biểu hiện thậm chí còn khó hiểu hơn chỉ sử dụng số dòng của dòng hiện đang đọc (AKA $.) nhưng Ruby không hỗ trợ điều đó.

Ngoài ra còn có tùy chọn sử dụng biểu thức thông thường, mà cư xử tương tự như việc so sánh theo thời gian:

File.foreach('/usr/share/dict/propernames') { |li| puts li if (li[/^Wa/] .. li[/^We/]) } 

Những kết quả đầu ra:

Wade 
Walt 
Walter 
Warren 
Wayne 
Wendell 

Bởi vì công việc regex, nó có thể tạo ra một mô hình phức tạp để truy xuất các dòng từ một tệp dựa trên các kết quả phù hợp. Là lần đầu tiên, sau đó kích hoạt mẫu thứ hai, dòng được bắt. Nếu, sau này trong tệp, một dòng khác sẽ kích hoạt mẫu đầu tiên, việc ghi lại sẽ xuất hiện lại cho đến khi mẫu thứ hai khớp với nhau. Đó là tuyệt vời mạnh mẽ:

File.foreach('/usr/share/dict/propernames') { |li| puts li if (
    li[/^Am/] .. li[/^An/] or 
    li[/^Wa/] .. li[/^We/] 
) 
} 

Những kết quả đầu ra:

Amanda 
Amarth 
Amedeo 
Ami 
Amigo 
Amir 
Amos 
Amy 
Anatole 
Wade 
Walt 
Walter 
Warren 
Wayne 
Wendell 

Hoặc luân phiên, cho bạn bè nói mơ hồ-mã của chúng tôi:

File.foreach('/usr/share/dict/propernames') { |li| puts li if (li[/^(?:Am|Wa)/] .. li[/^(?:An|We)/]) } 
1

Tôi tìm thấy một đoạn mã để minh họa cách các flip-flop hoạt động (chỉ trong cùng một cuốn sách mà đoạn mã này xuất hiện, hy vọng nó sẽ giúp cho những người có cùng một câu hỏi như tôi)

$state = false # Global storage for flip-flop state 
    def flipflop(x) # Test value of x against flip-flop 
     if !$state # If saved state is false 
      result = (x == 3) # Result is value of lefthand operand 
      if result # If that result is true 
       $state = !(x == 5) # Then saved state is not of the righthand operand 
      end 
      result # Return result 
     else # Otherwise, if saved state is true 
      $state = !(x == 5) # Then save the inverse of the righthand operand 
      true # And return true without testing lefthand 
     end 
    end 
0

Biểu thức flip-flop đánh giá đúng hoặc sai, giống như biểu thức so sánh và bình đẳng. Điều đặc biệt bất thường về biểu thức lật-flip, tuy nhiên, là giá trị của nó phụ thuộc vào giá trị của các đánh giá trước đó. Điều này có nghĩa là một biểu thức flip-flop có trạng thái kết hợp với nó; nó phải nhớ thông tin về các đánh giá trước đó.Bởi vì nó có nhà nước, bạn sẽ mong đợi một flip-flop là một đối tượng của một số loại. Nhưng không phải — đó là biểu thức Ruby, và trình thông dịch Ruby lưu trữ trạng thái (chỉ một giá trị Boolean đơn) mà nó yêu cầu trong biểu diễn phân tích nội bộ của biểu thức. Với nền tảng đó trong tâm trí, hãy xem xét flip-flop trong đoạn mã sau. Lưu ý rằng chữ ".." đầu tiên trong mã tạo đối tượng Range. Điều thứ hai tạo ra các biểu hiện flip-flop:

(1..10).each {|x| print x if x==3..x==5 } 

các flip-flop gồm hai biểu thức Boolean tham gia với các nhà điều hành .., trong bối cảnh của một điều kiện hoặc vòng lặp. Biểu thức flip-flop là sai trừ khi và cho đến khi biểu thức thứ tự ước tính là đúng. Khi biểu thức đó đã trở thành sự thật, cụm từ "lật" thành trạng thái thực sự bền vững. Nó vẫn còn trong trạng thái đó, và các đánh giá tiếp theo trả về true cho đến khi biểu thức đúng đánh giá là đúng. Khi đó xảy ra, flip-flop "flops" trở lại trạng thái sai liên tục. Các đánh giá tiếp theo của biểu thức trả về false cho đến khi biểu thức lefthand trở thành true một lần nữa. Trong ví dụ mã, flip-flop được đánh giá nhiều lần, cho các giá trị của x từ 1 đến 10. Nó bắt đầu ở trạng thái sai và đánh giá sai khi x là 1 và 2. Khi x == 3, flip-flop lật sang true và trả về true. Nó tiếp tục trở lại đúng khi x là 4 và 5. Khi x == 5, tuy nhiên, flip-flop flops trở lại false, và trả về false cho các giá trị còn lại của x. Kết quả là mã này in 345.