Pergunta

Aprendizagem rubi. Tenho a impressão de que atributos booleanos devem ser nomeados da seguinte forma:

my_boolean_attribute?

No entanto, eu recebo erros de sintaxe ao tentar fazer o seguinte:

class MyClass
  attr_accessor :my_boolean_attribute?

  def initialize
    :my_boolean_attribute? = false
  end
end

Aparentemente rubi é odiar o "?". Não é a convenção? O que estou fazendo de errado?

Foi útil?

Solução

Editar: três anos depois; os tempos, eles estão mudando ...

de Julik resposta é a maneira mais simples e melhor para resolver o problema nos dias de hoje:

class Foo
  attr_accessor :dead
  alias_method :dead?, :dead # will pick up the reader method
end

A minha resposta à pergunta original segue, para a posteridade ...


A versão curta:

Você não pode usar um ponto de interrogação em nome de uma variável de instância.

A versão mais longa:

Tome-se, por exemplo, attr_accessor :foo - é simplesmente conceitualmente um pouco de açúcar sintático para o seguinte:

def foo
  @foo
end

def foo=(newfoo)
  @foo = newfoo
end

Além disso, o sufixo de ponto de interrogação é na maior parte apenas uma convenção para indicar que o valor de retorno de um método é um boolean.

A melhor aproximação que eu posso fazer do que você está indo para aqui ...

class MyClass

  def initialize
    @awesome = true
  end

  def awesome?
    @awesome
  end

end

Neste caso, pode haver um caso a ser feito para usar attr_accessor - afinal, pode ser explícito que você está trabalhando diretamente com um atributo booleano. Geralmente, eu salvar o sufixo de ponto de interrogação para quando estou implementando um método cujo valor de retorno boolean é baseado em condições um pouco mais complexa do que apenas o valor de um atributo.

Felicidades!


Editar, dois anos mais tarde, depois de um comentário recente:

  1. Ruby obriga a certas convenções de nomenclatura. Símbolos em Ruby não pode ter pontos de interrogação. Assim invocações de :my_boolean_attribute? ambos vão falhar com um NameError Edit:. Não é correto, é só usar a sintaxe cotado para um símbolo, por exemplo, :"my_attribute?"
  2. Símbolos são imutáveis, a tentativa de atribuir a um vai jogar um SyntaxError.

Outras dicas

A maneira mais fácil de adicionar rapidamente um "método de pergunta" é utilizar aliasing para o seu método de leitura

class Foo
  attr_accessor :dead
  alias_method :dead?, :dead # will pick up the reader method
end 

O símbolo attr_accessor implica que o nome da variável é @my_boolean_attribute, então é isso que você deve ser de ajuste (não o símbolo).

Além disso, você não pode usar? para variáveis, os nomes apenas de método.

? é convenção para methodnames, não variáveis. Você não pode usar uma variável de instância nomeada @foo?, no entanto, você poderia usar uma variável chamada @foo e nome do (criado manualmente) método getter foo? se você quisesse.

metaprogramming Macaco-patch - talvez ele possa ser mais elegante, este é apenas um rascunho rápido, e eu não fiz metaprogramming por pouco tempo ...

 # inject the convenience method into the definition of the Object class
 class Object
   def Object::bool_attr(attrname)
     class_eval { define_method(attrname.to_s,
          lambda { instance_variable_get('@' + attrname.to_s.chop) }) }
     class_eval { define_method(attrname.to_s.chop+"=",
          lambda { |x| instance_variable_set('@'+attrname.to_s.chop, x) }) }
   end
 end

 ### somewhere later

 class MyClass

   bool_attr :my_boolean_attribute?

   def initialize
     @my_boolean_attribute = true
   end
 end

 # yet even more later

 foo = MyClass.new
 bar = MyClass.new

 foo.my_boolean_attribute = 1
 puts foo.my_boolean_attribute?
 puts bar.my_boolean_attribute?

Com esta abordagem, você pode ser seco e obter o bom questionmark também. Você só pode precisar escolher um nome melhor do que " bool_attr ", como, " bool_attr_accessor " ou algo similar.

As definições que eu fiz são um pouco irritadiço, no sentido de que o ponto de interrogação está presente no símbolo original. Provavelmente uma abordagem mais limpo seria para evitar o questionmark no nome do símbolo e anexá-lo durante a definição do método -. Deve ser menos confuso

Oh, e quase se esqueceu de incluir o link obrigatório: Vendo metaclasses claramente

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top