68

A method name can end with a question mark ?

def has_completed?
  return count > 10
end

but a variable name cannot.

What is the reason for that? Isn't it convenient to have variable names ending the same way too? Given that we usually can't tell whether foobar is a method or a variable just by looking at the name foobar anyway, why the exception for the ? case?

And how should I work with this? Maybe always to use has or is in the code?

if process_has_completed
  ...
end

if user_is_using_console
  ...
end
sawa
  • 165,429
  • 45
  • 277
  • 381
nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • 4
    As a side note: By convention, prefixes like `has_` or `is_` are not really popular in Ruby, therefore `def completed?` would be a better example. – svoop Mar 27 '11 at 13:10

2 Answers2

46

You'd have to ask Matz to get an authoritative answer. However,

  • Ruby is an untyped programming language and a variable like finished? would imply a specific type (boolean) which appears somewhat contradictory to me.
  • A question somewhat requires a receiver (who can answer the question). A method must have a receiver (the object the method is called on), so a question mark makes sense. A variable on the other hand has no receiver, it's a mere container.
sawa
  • 165,429
  • 45
  • 277
  • 381
svoop
  • 3,318
  • 1
  • 23
  • 41
  • 21
    then won't this apply to both method and variable names? Also, I think implying is nothing wrong, such as, if we don't use `?`, we probably use something else... and implying as well. Having `?` is just a convenient symbol to use. – nonopolarity Mar 27 '11 at 12:48
  • There is a difference as a variable holds a specific value whereas one single method could return values of different types. However, from a semantic point of view: Methods are messages sent to an object, so you could tell the object do do something or ask it for a value (hence the question mark). Variables are just holding a certain value. – svoop Mar 27 '11 at 13:02
  • 5
    Another argument for your semantic theory would be methods with exclamation mark. Methods with `?` and `!` could be seen as questions and orders given to an object. That doesn't make sanse for variables. – Mladen Jablanović Mar 27 '11 at 15:51
  • "You'd have to ask Matz to get an authoritative answer." Unless someone's already asked on one of the Ruby mailing lists... – Andrew Grimm Mar 27 '11 at 22:53
  • Can you post the link? I'd like to know what Matz has to say about this. – svoop Mar 28 '11 at 17:40
  • @svoop: I don't know whether he's been asked or not. – Andrew Grimm Mar 29 '11 at 01:22
  • 6
    I don't really buy this reasoning, or at least that it makes sense in Ruby as it exists today. Just because Ruby is untyped doesn't mean that names shouldn't imply types. Almost always the opposite. If a variable is called `full_name`, it's almost definitely not going to be a floating point number. By contrast, in typed programming, there actually are times when a name _shouldn't_ imply a type -- when working with generics. The receiver thing also doesn't hold up, because it's common practice to use getters and setters to treat methods as though they were variables within a scope or block. – acjay Nov 10 '17 at 23:57
  • It's a shame that this isn't possible. Sometimes it'd be nice to be able to define procs with `?` in the name. i.e. `success? = ->(arr) { !arr.empty? }`... – XtraSimplicity Jan 05 '20 at 21:16
  • Lambdas are somehow similar to methods, so in example for me would make sense to do `present? = ->(str) { !str.blank? }` `[''a', 'b', nil].keep_if(&present?)`, but it's not possible. – Pere Joan Martorell Jan 14 '22 at 18:07
  • Really _all_ methods that return a value are asking their receiver something, so by this answer's logic should all end in a `?`. (`user.full_name` is "asking" what the user's full name is.) The true intent of the `?` is to suggest that the method returns a boolean. A `?` on the end of a variable name would likewise suggest that the variable should _be_ a boolean -- which makes the same amount of sense in the same way. The issue comes up when memoizing methods, e.g. `def valid?; @valid ||= [some boolean expression]; end`. The instance variable should have the same name as the method, but can't. – user1070300 Jan 10 '23 at 21:48
6

Now this is just a thought, but I think methods with names like empty? suggest that a some sort of check has to be made inside and object or a class (depending on the context). This check or evaluation means an action must be done. Overall, since we are asking (thus, ?) object for some state, means there is a possibility that object's state could change throughout the application's lifecycle. A variable could be outdated, but ?-method (check) will be done in the specific moment, thus providing an up-to-date information on some state that could be presented in a boolean form.

So I'd like to think that this is a design constraint provided by the architect (Matz) to enforce a more logical, close-to-real-life coding approach.

Ziggy
  • 227
  • 1
  • 5
  • As I mentioned in another comment, this reasoning applies to _any_ method that returns a value from an object -- you're "asking" what the value is, whether the answer is a string, float, boolean, or whatever. What the `?` actually means (and the only thing it means) is that the method should return a boolean -- even though it's just a naming convention, and Ruby does nothing to enforce it. I've not seen any coherent argument as to why this naming convention wouldn't make exactly the same amount of sense applied to variables. – user1070300 Jan 10 '23 at 22:06