2015-06-10 22 views
7

Mã này được cung cấp làm ví dụ để sử dụng với kiến ​​thức và OmniAuth, mã này hoạt động trong my project.Tại sao duy nhất `=` làm việc trong câu lệnh `if`?

class User < ActiveRecord::Base 
    def self.new_with_session(params, session) 
    super.tap do |user| 
     if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"] 
     user.email = data["email"] if user.email.blank? 
     end 
    end 
    end 
end 

Tôi không biết lý do tại sao nó là một bình đẳng đơn đăng ký đối lập với sự bình đẳng một đôi ký, mà tôi nghĩ là cần thiết cho if -statements. IDE "intelliJ IDEA" của tôi đồng ý với những lo ngại của tôi.

Trả lời

7

Điều cần thiết duy nhất cho tuyên bố if hợp lệ là biểu thức boolean. Trong trường hợp này, kể từ khi = trả lại kết quả của bài tập, những gì thực sự đang được thử nghiệm là giả mạo của session["devise.facebook_data"].

IntelliJ có một điểm tốt để khiếu nại về mã như thế này, vì khó đọc mà không biết một hoặc hai điều về Ruby. Một đề xuất sẽ được chuyển sang câu lệnh gán rõ ràng thay thế. Điều này có thêm lợi ích của DRYing lên một tham chiếu đến nó hai lần.

class User < ActiveRecord::Base 
    def self.new_with_session(params, session) 
    super.tap do |user| 
     data = session["devise.facebook_data"] 
     if data && data["extra"]["raw_info"] 
     user.email = data["email"] if user.email.blank? 
     end 
    end 
    end 
end 
+0

Cảm ơn !! Làm cho ý nghĩa bây giờ, bạn giải thích rằng hoàn hảo. – thesowismine

+0

Không chắc chắn ý của bạn là "điều cần thiết ... là hợp lệ là một biểu thức boolean." Bất kỳ đối tượng nào cũng có thể xuất hiện sau 'if'. Có bất kỳ đối tượng "không boolean" mà bạn có trong tâm trí mà sẽ làm cho một điều kiện 'if' bất hợp pháp? – sawa

+0

@sawa Khi tôi ở gần máy tôi có thể sửa lại phần đó. – Makoto

2

Trong Ruby, một dấu bằng đơn được sử dụng để gán . Khái niệm

data = session["devise.facebook_data"] 

gán kết quả của đánh giá session["devise.facebook_data"] cho một biến địa phương tên là data.

Nếu mã băm session không có khóa "devise.facebook_data", mã sẽ trả lại nildata sẽ được gán nil. Bài tập đánh giá giá trị được gán, do đó bài tập cũng sẽ đánh giá là nil. nil được coi là falsey trong một bối cảnh boolean, do đó, toán hạng bên phải của && sẽ không được đánh giá. Bằng cách đó, bạn sẽ không nhận được số NoMethodError đang cố gắng gọi nil["extra"]["raw_info"].

Nếu session băm không có một chìa khóa "devise.facebook_data", data sẽ được thiết lập với giá trị liên kết với nó. Bất kỳ giá trị nào khác ngoài nilfalse được coi là trung thực, do đó toán hạng bên phải của toán tử && sẽ được đánh giá.

Nếu điều kiện là trung thực, mệnh đề then sẽ được đánh giá, sử dụng biến số data được chỉ định trong điều kiện.


Lưu ý: Tôi tin rằng người ta cũng có thể sử dụng các biến data trong phía bên tay phải của các nhà điều hành &&, tức là tình trạng này có thể đọc như thay vì điều này:

if data = session["devise.facebook_data"] && data["extra"]["raw_info"] 

Nhưng tôi sẽ phải để kiểm tra điều đó.

+0

Yea thats những gì tôi nghĩ, tôi đoán im chỉ nhầm lẫn với bố cục của hàm. Có thể bạn có thể giải thích chính xác những gì nếu được yêu cầu? Tôi thấy &&, nhưng nó có vẻ như theres nhiều hơn thế? – thesowismine

+0

'if' đầu tiên tương đương với' data = ... 'theo sau là' if data; user.email = ... '. –

1

Toán tử gán (=) trả về giá trị đã gán, sau đó được đánh giá bởi if. Trong ruby, chỉ falsenil được coi là false. Mọi thứ khác đều đánh giá thành true trong ngữ cảnh boolean (như if).

0

Ruby không quan tâm đến các loại trong điều kiện, không giống Java. Miễn là giá trị không phải là không hoặc không thì nó sẽ vượt qua.

Trong ví dụ của bạn, bạn thực sự phân biệt đối xử với nil: nếu điều kiện đảm bảo rằng dữ liệu thực sự tồn tại và không phải là không, vì vậy chúng tôi có thể sử dụng nó, giả sử đó là một băm. Đây là một mô hình phổ biến trong Ruby.

+0

Trên thực tế, có hay không một giá trị là falesy hay không ** được xác định bởi loại của nó (lớp) **, tức là, nếu nó là một thể hiện của 'NilClass' hoặc' FalseClass', sau đó nó là falesy. – sawa

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