Toán tử dấu hỏi có ý nghĩa gì trong Ruby?


211

Mục đích của toán tử dấu hỏi trong Ruby là gì?

Đôi khi nó xuất hiện như thế này:

assert !product.valid?

đôi khi nó trong một ifcấu trúc.


2
Dấu hỏi ở cuối hàm không phải là toán tử, nó là ký tự bình thường. Dấu hỏi cùng với dấu hai chấm là một toán tử điều kiện ternary. Dấu hỏi của chính nó là một toán tử trích dẫn đơn nhất. Xem stackoverflow.com/questions/16641205/ từ
Old Pro

Câu trả lời:


296

Đó là một quy ước kiểu mã; nó chỉ ra rằng một phương thức trả về giá trị boolean.

Dấu hỏi là một ký tự hợp lệ ở cuối tên phương thức.


9
Cảm ơn, nhưng quy ước này có nghĩa là nó chỉ logic hay có thể có tác dụng phụ? Thật buồn cười là đây là một loại hack xung quanh một ngôn ngữ được gõ với kiểu trả về trong mã.
Jason

5
Trong trường hợp này, nó đúng là một quy ước đặt tên phương pháp. Không có sự thi hành của giá trị trả về boolean. Chỉ vì tên phương thức kết thúc bằng dấu chấm hỏi không có nghĩa là phương thức phải trả về boolean ... nhưng chắc chắn nó sẽ trả về boolean. Tuy nhiên, có một số cách sử dụng khác ?trong Ruby (là toán tử ternary, chuyển đổi một ký tự thành số nguyên ASCII của nó, sử dụng testtrong RegEx'es, v.v.) nhiều trong số đó được đề cập trong các câu trả lời khác ở đây.
Karl Wilbur

4
@Jason FYI, ngay cả những ngôn ngữ được gõ mạnh cũng có những quy ước như thế này. Ví dụ, trong phương thức Java mà trả về một giá trị boolean thường bắt đầu bằng "là", như trong isEmpty(), isDigit()vv Trong Ruby, các phương pháp tương tự sẽ được viết empty?, và digit?đó là khá một chút đẹp hơn IMO.
Ajedi32

3
Ajedi32 - Vâng, tôi đồng ý rằng thật tuyệt khi đặt tên cho các chức năng như vậy, tôi sử dụng ismọi lúc. Điều này có thể gây nhầm lẫn cho ai đó đến từ Swift vì dấu hỏi được sử dụng cho nullable:)
Jason

83

Cũng lưu ý ?cùng với một ký tự, sẽ trả về mã ký tự ASCII choA

Ví dụ:

?F # => will return 70

Luân phiên trong ruby ​​1.8 bạn có thể làm:

"F"[0]

hoặc trong ruby ​​1.9:

"F".ord

Cũng lưu ý rằng ?Fsẽ trả về chuỗi "F", vì vậy để làm cho mã ngắn hơn, bạn cũng có thể sử dụng ?F.ordtrong Ruby 1.9 để có kết quả tương tự như "F".ord.


29
Trong ruby ​​1.9, nó sẽ trở lại'F'
klew

39

Đó là một quy ước trong Ruby rằng các phương thức trả về giá trị boolean kết thúc bằng dấu chấm hỏi. Không có ý nghĩa gì hơn thế.


28

Trong ví dụ của bạn, nó chỉ là một phần của tên phương thức. Trong Ruby, bạn cũng có thể sử dụng dấu chấm than trong tên phương thức!

Một ví dụ khác về các dấu hỏi trong Ruby sẽ là toán tử ternary.

customerName == "Fred" ? "Hello Fred" : "Who are you?"

13
Để mở rộng câu trả lời của Andy, bạn cũng sẽ thấy những thứ như: customerName == user.logged_in? ? user.name: "Bạn là ai?" Lưu ý dấu chấm hỏi kép
Dấu hỏi

16

Trong ví dụ của bạn

product.valid?

Thực sự là một chức năng gọi và gọi một chức năng có tên valid?. Một số loại "kiểm tra điều kiện" / hàm boolean nhất định có dấu chấm hỏi như một phần của tên hàm theo quy ước.


41
answer.gsub! (/ function /, 'method')
glenn jackman

15

Có thể chỉ ra rằng ?s chỉ được phép trong tên phương thức, không phải biến. Trong quá trình học Ruby, tôi giả định rằng đã ?chỉ định loại trả về boolean nên tôi đã thử thêm chúng vào các biến cờ, dẫn đến lỗi. Điều này dẫn đến việc tôi đã sai lầm khi tin rằng có một số cú pháp đặc biệt liên quan đến ?s.

Có liên quan: Tại sao tên biến không thể kết thúc bằng `?` Trong khi tên phương thức có thể?


9

Tôi tin rằng đó chỉ là một quy ước cho những thứ mang tính boolean. Một chút như nói " IsValid".


1
bình luận ngắn gọn và tuyệt vời đặc biệt "Một chút như nói" IsValid "
Kick Buttowski

2

Nó cũng được sử dụng trong các biểu thức chính quy, có nghĩa là "nhiều nhất một lần lặp lại của ký tự trước"

ví dụ: biểu thức chính quy /hey?/ khớp với các chuỗi " he" và " hey".


0

Đây cũng là một quy ước phổ biến để sử dụng với đối số đầu tiên của phương thức thử nghiệm từ Kernel # test

irb(main):001:0> test ?d, "/dev" # directory exists?
=> true
irb(main):002:0> test ?-, "/etc/hosts", "/etc/hosts" # are the files identical
=> true

như đã thấy trong câu hỏi này ở đây


3
Nó không liên quan đến test, ?dlà một phím tắt cho "d". testlấy một chuỗi một char làm đối số đầu tiên của nó, vì vậy bạn có thể gọi nó bằng test ?d, "/dev"hoặc test "d", "/dev".
bfontaine
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.