2010-09-18 31 views
15

Một số phiên bản tiếng nổ của Array phương pháp này như compact!, reject!, flatten!, uniq! trở nil nếu không có những thay đổi đã được thực hiện:Hành vi của Array phương pháp nổ

[1,[2]].flatten! 
# => [1, 2] 
[1,2].flatten! 
# => nil 
[1,[2]].flatten 
# => [1, 2] 
[1,2].flatten 
# => [1, 2] 

[1,2,nil].compact! 
# => [1, 2] 
[1,2].compact! 
# => nil 
[1,2,nil].compact 
# => [1, 2] 
[1,2].compact 
# => [1, 2] 

Nếu họ đã làm nó theo cách này, phải có một lý do. Bất cứ ý kiến ​​nào có được không?

Trả lời

18

Phương pháp bang (!) sửa đổi đối tượng hiện tại tại chỗ, nhưng chúng trả lại nil nếu không có yếu tố bị ảnh hưởng trên the documentation. Điều này rất hữu ích nếu, vì lý do gì, bạn cần phải làm điều gì đó nếu bạn đã sửa đổi mảng được đề cập.

if array.flatten! 
    puts "Oh yeah... flattened that array!" 
end 
+2

Đó là một điểm tốt. Nhưng bạn không thể nói 'return array.flatten!', Với tôi, có vẻ hữu ích hoặc là – artemave

+0

True. Nếu đó là những gì bạn muốn, bạn sẽ nói 'return array.flatten' (no bang) sẽ trả lại cho bạn một bản sao phẳng của mảng ban đầu. –

+6

Tôi buộc phải tạo một bản sao mà tôi không cần. Đó là chính xác làm thế nào tôi đã gặp rắc rối bằng cách sử dụng phiên bản đập ở nơi đầu tiên. – artemave

4

Tôi đã luôn luôn theo ấn tượng rằng nổ phiên bản của phương pháp này là Array chỉ khác nhau trong cách mà họ sửa đổi đối tượng tại chỗ.

Có lẽ vấn đề ở đây là ấn tượng này là không thực sự là một đúng một: according to David A. Black, ! không có nghĩa là phương pháp thay đổi nhận của nó; ! có nghĩa là phương pháp này là phiên bản "nguy hiểm" của phương pháp tương đương, có cùng tên trừ !.

Bây giờ nguy hiểm có nhiều hình thức (nhấn mạnh tôi):

Đôi khi bạn nhận được nhiều hơn một loại của "nguy hiểm" thậm chí trong vòng một tiếng nổ phương pháp. Hãy String#gsub!. phương pháp này thay đổi nhận nó:

str = "David" 
str.gsub!(/$/, " Black") 
str      # David Black 

Nó cũng khác với gsub (phi-bang) ở chỗ nếu chuỗi không thay đổi, gsub trả về một bản sao của thay đổi chuỗi nhưng gsub! lợi nhuận Nil:

str.gsub(/xyz/, "blah") # David Black 
str.gsub!(/xyz/, "blah") # nil 
str      # David Black 

! trong gsub! cung cấp cho bạn thông báo: cảnh báo bạn về nguy hiểm và điều đó có nghĩa là trước khi bạn sử dụng phương pháp, bạn nên tìm hiểu chính xác cách thức hoạt động của nó . (A đơn giản "ri String#gsub!" nên làm điều đó.)

này "heads-up" ngữ nghĩa cũng áp dụng cho các phương pháp nổ của Array.

+2

Tôi cũng đọc bài đăng này - nó không có ý nghĩa. Ý nghĩa của 'nguy hiểm' được xác định là một dấu hiệu của hành vi phản trực giác. Vâng, có lẽ, họ không nên làm theo cách đó ngay từ đầu? – artemave

+1

Và 'trước khi bạn sử dụng phương pháp, bạn nên tìm hiểu chính xác cách hoạt động của nó 'rõ ràng không phải là cách ruby, nơi mà toàn bộ hệ sinh thái của các quy ước tự nhiên dẫn đến điều đúng. – artemave

Các vấn đề liên quan