1

In ruby, most methods or keywords that end with ? return boolean values. And we except them to behave like this. Why does defined? keyword return somethings else? Or why is there ? at the end of it?

sawa
  • 165,429
  • 45
  • 277
  • 381
sayginburak
  • 87
  • 1
  • 7

3 Answers3

2

Developers chose to return something more meaningfull than true or false because the only case that breaks by not having boolean returned is explicit comparison:

defined?(:x) == true
# => always `false`

Such comparison is something you should usually not do, as logical operators like || and && are just as likely to return some truthy object instead of true. This is barely needed for anything.

sawa
  • 165,429
  • 45
  • 277
  • 381
Borsunho
  • 1,127
  • 7
  • 21
2

This question can be understood in two ways:

  1. Why doesn't it simply return true or false?

It's because it encodes more information than simply if something is defined or not:

defined? Class # => "constant"
defined? 42    # => "expression"
defined? nil   # => "nil"
defined? x     # => nil
  1. Why does it have ? at the end since as the convention goes, the question mark is reserved for predicates?

You are right that this is inconsistent. The most likely reasons are:

  • Almost always, you will use it as predicate anyway

    if defined? x
      # do something
    end
    
  • The shortest alternative, which doesn't sound like a predicate I can think of is definition_type_of. Generally, you want to keep the reserved words in your language short

ndnenkov
  • 35,425
  • 9
  • 72
  • 104
  • 2
    For me, the really wtf part around `defined?` has always been *why does it return strings and not symbols?*. I have absolutely no good answer for that... – ndnenkov Aug 28 '15 at 12:02
-1

The "defined?"-method can return more than "true" or "false". It tells you what type of variable it is if it's defined at all.

Check Checking if a variable is defined? and http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-defined-3F

Community
  • 1
  • 1
Blackorade
  • 67
  • 6