Ruby tem uma ideia universal de " veracidade " e " falsidade ".
Rubi faz ter duas classes específicas de objetos booleano, TrueClass
e FalseClass
, com as instâncias únicas indicadas pelas variáveis especiais true
e false
, respectivamente.
No entanto, truthiness e falsiness não estão limitados a instâncias dessas duas classes, o conceito é universal e se aplica a cada objeto em Ruby. Cada objeto é ou truthy ou Falsas . As regras são muito simples. Em particular, apenas dois objetos são falsos :
nil
, a instância singleton deNilClass
efalse
, a instância singleton deFalseClass
Todo outro objeto é verdadeiro . Isso inclui até objetos que são considerados falsos em outras linguagens de programação, como
Essas regras são incorporadas ao idioma e não podem ser definidas pelo usuário. Não há to_bool
conversão implícita ou algo semelhante.
Aqui está uma citação da ISO Ruby Language Specification :
6.6 Valores booleanos
Um objeto é classificado em um objeto trueish ou falso .
Somente false e nil são objetos falsos. false é a única instância da classe
FalseClass
(consulte 15.2.6), para a qual uma expressão falsa avalia (consulte 11.5.4.8.3). nil é a única instância da classeNilClass
(consulte 15.2.4), para a qual uma expressão nula é avaliada (consulte 11.5.4.8.2).Objetos diferentes de false e nil são classificados em objetos trueish. true é a única instância da classe
TrueClass
(consulte 15.2.5), para a qual uma expressão true é avaliada (consulte 11.5.4.8.3).
O executável Ruby / Spec parece concordar :
it "considers a non-nil and non-boolean object in expression result as true" do if mock('x') 123 else 456 end.should == 123 end
De acordo com essas duas fontes, eu assumiria que Regexp
s também são verdadeiros , mas de acordo com meus testes, eles não são:
if // then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are falsy'
Eu testei isso no YARV 2.7.0-preview1 , no TruffleRuby 19.2.0.1 e no JRuby 9.2.8.0 . Todas as três implementações concordam entre si e discordam da ISO Ruby Language Specification e da minha interpretação do Ruby / Spec.
Mais precisamente, os Regexp
objetos resultantes da avaliação de Regexp
literais são falsos , enquanto os Regexp
objetos resultantes de alguma outra expressão são verdadeiros :
r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'
Isso é um bug ou comportamento desejado?
!!//
é falso, mas !!/r/
é verdadeiro. Estranho mesmo.
!!/r/
produz false
para mim usando (RVM) Ruby 2.4.1.
//
em if // then
é interpretado como um teste (um atalho para if //=~nil then
) (que é sempre Falsas qualquer que seja o padrão) e não como uma instância Regexp.
Regex.new("a")
é verdade.