Pergunta

Eu tenho um sistema de templates muito antigo escrito em cima de ERB. Ele se baseia em modelos de ERB armazenados no banco de dados. Aqueles são lidos e processados. Quando eu quero passar dados de um modelo para outro eu uso o: habitantes locais parâmetro para Rails método render. Para definir variáveis ??padrão dessas variáveis ??em alguns modelos eu uso o definido? método que simplesmente me diz se variável local foi definido e se não eu inicializá-lo com valor padrão como este:

unless defined?(perex)
  perex = true
end

Eu estou atualizando o app mais Rails e eu ver algum comportamento estranho. Basicamente isso às vezes funciona (por vezes perex é indefinido) e às vezes isso não acontece (perex é definido e definir a zero). Isto acontece sem qualquer outra coisa mudando.

Eu tenho duas perguntas: Existe alguma maneira melhor à excepção de usar definido? que se tem revelado pouco confiável (era confiável por vários anos sobre trilhos superiores 1.6)? de tal forma não deve resultar em me reescrever todos os modelos. Eu fui passando docs Ruby e não era capaz de encontrar qualquer coisa sobre definido? método. Foi preterido ou estou apenas cego simples?

Editar: A questão real foi causada pelo que parece ser um bug Ruby / ERB. Às vezes, a menos declaração iria funcionar, mas às vezes não. O estranho é que, mesmo se a segunda linha tem executado perex stil ficou nulo para o resto do mundo. Removendo definido? resolvido isso.

Foi útil?

Solução

Primeiro: na verdade, defined? é um operador <. / p>

Segundo: se eu entendi sua pergunta, a maneira de fazer isso é com esta expressão Ruby:

perex ||= true

Isso vai atribuir fiel a perex se for indefinido ou nil. Não é exatamente o que o seu exemplo faz, desde o seu não avaliar a atribuição quando o valor é nil, mas se você está confiando em que, em seguida, na minha opinião, sem vê-lo, você não está escrevendo código claro.

Editar : Como Honza observou, a declaração acima irá substituir o valor de perex quando é false. Então eu proponho o seguinte para reescrever o número mínimo de linhas:

perex ||= perex.nil?  # Assign true only when perex is undefined or nil

Outras dicas

A maneira mais segura de testar se um local é definida em um modelo de Rails é:

local_assigns[:perex]

Isso está documentado na API do Rails juntamente com a explicação de que defined? não pode ser usado devido a uma restrição de implementação.

A resposta de Per Mislav, eu fui à procura de que a documentação da API do Rails, e encontrou-o em Class ActionView :: base (sob o título "Passando variáveis ??locais para sub modelos"). Era dificilmente vale a pesquisa, no entanto, uma vez que quase não disse nada mais do que Mislav fez. Exceto que ele recomenda este padrão:

if local_assigns.has_key? :perex

Tendo em resposta original considerationg do Mislav e o KenB elaboração , acho que o seguinte é a melhor abordagem absoluta (embora estou aberto a opinião). Ele utiliza Ruby Hash # buscar método para fallback em um valor alternativo se a chave não existe no hash originais.

perex = local_assigns.fetch(:perex, true)

Isto é ainda melhor do que o método ||= que a maioria dos usuários irá sugerir desde às vezes você vai querer permitir que os valores false. Por exemplo, o seguinte código irá não permitir que um valor false a serem passados ??em:

perex = local_assigns[:perex] || true
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top