Galera, começei a estudar Ruby e muitas dúvidas surgiram.
Uma delas é a seguinte… no Java eu declaro uma variável privada e defino get’s e set’s, neste caso eu poderia usar o método set para validar a informação, por exemplo:
class People{
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
if(age < 0){
this.age = 0
}else{
this.age = age;
}
}
}
Em ruby eu vi que existe um atalho para a criação desses métodos de acesso, por exemplo:
class People
attr_accessor :age
end
Mas existe alguma forma de validar se a idade é menor que zero utilizando esse atalho, ou teria que implementar um método tipo esse:
def age=(age)
@age = age
end
.[/quote]
a forma mais simples é essa mesmo, criando o método setter. não dá pra ser mais econômico
qualquer tentativa de simplificar isso vai piorar e deixar o código ilegível com metaprogramming.
def age=(age)
@age = age
end
.[/quote]
a forma mais simples é essa mesmo, criando o método setter. não dá pra ser mais econômico
qualquer tentativa de simplificar isso vai piorar e deixar o código ilegível com metaprogramming.[/quote]
Poderia ter postado ao menos no post original e não neste que é o duplicado…
de qualquer forma, não consigo ver como usar as validações do Active Record tornam o código ilegível:
class Person < ActiveRecord::Base
validates :age, numericality: { only_integer: true, greather_than: 0 }
end
[quote=Ataxexe]de qualquer forma, não consigo ver como usar as validações do Active Record tornam o código ilegível:
class Person < ActiveRecord::Base
validates :age, numericality: { only_integer: true, greather_than: 0 }
end
[/quote]
o exemplo dele não usa AR. É uma Ruby class simples.
Mesmo que usasse AR, acho ele não quer validar: quer assegurar que ages menores que 0 chegem a 0
EDITED:
Havia ainda um terceiro post duplicado e eu não havia reparado. Olhei para aquele com a descrição vazia…sorry
meu ponto sobre ilegibilidade não é o produto final, mas sim o meta-código que dará trabalho pra entender 6 meses depois. Para o caso de economizar um mísero IF como no exemplo, não vejo necessidade de criar um helper method que vai adicionar mais linhas de código no fim das contas
Não é bem um mísero if porque você tem uma segunda instrução aí:
def age=(n)
age = n.to_i
raise Error if n < 1 #ou a loucura de colocar o age como zero (mas aí pode ser com um if/else na atribuição
@age = age
end
O "to_i" serve para converter para inteiro (ou teremos 23.5 anos, o que só é válido em alguns casos isolados e mesmo assim seria calculado com base na data de nascimento). E não precisamos criar um helper, pode-se importar gems de validação para isso.
E se alguém não entender o helper 6 meses depois é porque não o escreveu direito e se não entender a utilização do helper é porque não sabe ler.
Ficou confuso mesmo porque ele se referiu a validação durante o post inteiro. Mas o exemplo dele não é bem uma validação.
Eu não seria tão defensivo assim…
Não dá pra simplesmente fazer isso?
def age=(n)
@age = [n.to_i, 0].max # thanks Math!
end
Sim, obviamente. Mas importar uma gem pra validar que o age não pode ser menor que 0???
De novo, metaprogramming pra isso? Quando existem N outras formas pragmáticas de resolver o problema? Várias literaturas e a comunidade como um todo tem percebido que metaprogramming tem que ser usado com moderação. É questão de avaliar custos: compensa fazer toda essa volta pra verificar apenas que o age não pode ser menor que 0? Esse que é meu ponto. Meta é a última coisa que eu vou fazer, quando não há nenhuma solução simples na stdlib para aquilo.
Acho que o autor do tópico colocou isso em questão, porque como no começo ouvimos aquela moda em falar que Ruby faz “magias”, ele suspeitou que poderia ter algo mágico já pronto. Só que tem que ver o custo desse “pronto”.
Claro que, se ele for usar AR (ou até memo o ActiveModel apenas), já ganha de lambuja essas validações. Mas no caso de um simples PORO sei lá, não vejo necessidade
Dá sim, embora não seja o mesmo efeito por causa da Exceção. O seu exemplo se aproxima mais do código Java do autor, eu soquei um raise lá só pra ilustrar também outra forma.
Eu entendo seu ponto, e se avaliarmos somente o código do post realmente não seria necessário importar uma gem só pra esse caso, mas se tivermos outro e outro e por aí em diante pode ser uma boa usar esse recurso.
[quote]
Acho que o autor do tópico colocou isso em questão, porque como no começo ouvimos aquela moda em falar que Ruby faz “magias”, ele suspeitou que poderia ter algo mágico já pronto. Só que tem que ver o custo desse “pronto”.
Claro que, se ele for usar AR (ou até memo o ActiveModel apenas), já ganha de lambuja essas validações. Mas no caso de um simples PORO sei lá, não vejo necessidade[/quote]
Eu entendo, só postei o lado metaprogramming disso por causa da sua última frase da primeira mensagem:
[quote=Ataxexe]Eu entendo, só postei o lado metaprogramming disso por causa da sua última frase da primeira mensagem:
Verdade, acho que não conssegui me expressar bem. Não sou contra meta, aliás, já precisei fazer muito meta nessa vida
Mas por experiência própria e também aprendendo com os outros, prefiro adotar metaprogramming (inicialmente) como um “anti-pattern” até que se prove o contrário e seu uso traga realmente valor.
Eu também não sou muito fã de abusar de metaprogramação, é mais ou menos o mesmo que abusar de reflexão no java. Uma vez eu fiz umas loucuras com essas magias negras do ruby que me deu até medo de continuar usando adoidado (o que mais me deu medo foi definir métodos dinamicamente cujos nomes também eram dinâmicos - foi quase uma “inception”). É legal pra impressionar, mas não dá pra abusar mesmo.