This page is READ-ONLY. It is generated from the old site.
All timestamps are relative to 2013 (when this page is generated).
If you are looking for TeX support, please go to VietTUG.org

trùng địa chỉ. gán song song

lolz
Added by almost 3 years ago  »  Votes: 1/1

Ta đi xây dựng pslit(pat) như sau. Hàm sẽ tách một mảng các chuỗi đã có thành hai phần: một phần gồm các phần tử có chứa chuỗi pat, phần còn lại gồm các phần tử không hợp lệ (không phải chuỗi, hoặc là chuỗi nhưng không chứa chuỗi pat). Kết quả trả về của hàm là một Hash.

 1 class Array
 2   def pslit(pat)
 3     matched = unmatched = []
 4     self.each do |item|
 5      if item.is_a?(String) and item.include?(pat)
 6        matched << item
 7      else
 8        unmatched << item
 9      end
10     end
11     {:matched => matched, :unmatched => unmatched}
12   end
13 end

Mọi việc có vẻ ổn nhỉ? Hãy thử xem

1 src = ["test", "this", "that", "there"]
2 ret = src.pslit('at')
3 ret[:matched]   == src # => true
4 ret[:unmatched] == src # => true

Thật là tệ hại! Đúng ra, ret[:matched] sẽ là ['that'] và nó không thể bằng với mảng gốc src được.

Tại sao như vậy? Sai sót nằm ở ngay phép khai báo đầu tiên:

1 matched = unmatched = []

Với phép gán này, địa chỉ của hai mảng matchedunmatched trùng nhau hoàn toàn. Do đó, việc bổ sung phần từ vào unmatched cũng là bổ sung phần tử vào matched. Kết quả là hai mảng phụ này sẽ hoàn tòan giống nhau :))

Hàm pslit sẽ làm việc đúng ý đồ thiết kế nếu chỉnh lại như sau

1 matched, unmatched = [], []

Đó là một phép gán song song. Nếu lười biếng và nhầm lẫn thì sẽ tai hại như đã chỉ ra ở trên.


Comments