Ruby Beans (propriedades de um objeto Ruby)

Em Java temos a útil convenção de que métodos getters (getXXXX) retornam uma propriedade de um objeto.

E em Ruby?

Tenho um objeto é quero listar via reflection todas as suas propriedades. Devo assumir que todo método sem parametros e que retorna algo (e não termina com ‘?’, ‘=’ ou ‘!’) é uma propriedade?

Ter acesso direto às variáveis de instância usando instance_variables não resolveria seu problema?
Você pode obter e modificar seus valores usando instance_variable_get e instance_variable_set, respectivamente.

[quote=tnaires]Ter acesso direto às variáveis de instância usando instance_variables não resolveria seu problema?
Você pode obter e modificar seus valores usando instance_variable_get e instance_variable_set, respectivamente.[/quote]

Variável de instância é BEM diferente de propriedade. A primeira é privada e interna e a segunda pode não ter qualquer ligação com a primeira.

Ex:

private long birthdate;

public Date getBirthdate() {

   return new Date(birthdate);
}

public int getDaysToBirthdate() {
  
   return new Date() - birthdate; // como faz falta operator overloading para datas em Java...

}

Parece que falta uma convenção em Ruby para dizer quando um método é um getter de uma propriedade. Ou ela existe e eu não a conheço, por isso a pergunta.

Não estou bem certo se entendi.
Dentro do contexto da sua explicação, para que uma variável de instância seja uma propriedade em Java, basta atribuir um getter ( read-only ) ou um getter e um setter, certo?
Então o equivalente em Ruby são as declarações attr_reader, attr_writer e attr_accessor.

[quote=tnaires]Não estou bem certo se entendi.
Dentro do contexto da sua explicação, para que uma variável de instância seja uma propriedade em Java, basta atribuir um getter ( read-only ) ou um getter e um setter, certo?
Então o equivalente em Ruby são as declarações attr_reader, attr_writer e attr_accessor.[/quote]

O que eu quiz dizer é que uma variável de instancia não é obrigatoriamente uma propriedade, seja em Ruby, em Java ou em qualquer outra linguagem OO que possua encapsulamento. O meu exemplo de código mostra isso.

Em Ruby não há a convenção de getXXXX, logo como saber quais métodos getters indicam propriedades? Em Java tudo que é getXXX sem parametros é uma propriedade, ou pelo menos é essa a convenção desde os primórdios da linguagem (JavaBeans).

Cospe na cara do Demeter, mesmo. :frowning:

http://www.pragprog.com/articles/tell-dont-ask

Mas, ja que eu sei que vc eh cabeca dura e nao vai desistir, o melhor jeito eh criar algo do tipo:

[code]class Foo
include Properties
property :bar
property :baz
end

f = Foo.new
f.bar = "hello"
f.baz = “world”

f.properties # == [:bar, :baz]
f.properties.include? :bar # == true
f.properties.include? :baz # == true
f.properties.include? :meh # == false[/code]

:attr_reader & cia: http://www.ruby-doc.org/docs/UsersGuide/rg/accessors.html

Se teu código precisa de muitos accessors ele tem um sério problema de design.

[quote=cv]Cospe na cara do Demeter, mesmo. :frowning:

http://www.pragprog.com/articles/tell-dont-ask
[/quote]

Interessante. É que no meu caso tudo que eu quero é, via reflection, imprimir todas as propriedades públicas de um objeto. Nada de muito complexo ou pecaminoso.

Bem legal essa sua idéia, mas eu ou vc ou qualquer um pode criar seu próprio esquema de propriedades para objetos Ruby. Cheguei até a pensar que esse Properties que você incluiu era do próprio Ruby, mas procurando no RDocs não encontrei nada parecido. Me parece natural termos uma convenção onde todos usariam o mesmo esquema para indicar uma propriedade pública, assim como em Java usamos métodos getters (getXXXX) sem argumentos.

Se hoje vc me passa um objeto Cidade e eu quero imprimir e/ou ter acesso a todas suas propriedades como CEP => ‘22222-123’, Name => ‘Rio de Janeiro’, Estado = ‘RJ’, etc. Como eu faço? Bisbilhotar variáveis de instancia que por definição são privadas não me parece sadio. Chamar todos os métodos sem parametros seria insano.

Só queria realmente saber se há alguma convenção para isso da própria linguagem ou não.

Sim, assim como se vc come muitas batatas-fritas terá sérios problemas gastro-intestinais (vide o filme Super Size Me). Propriedades me parece algo tão trivial quanto batatas-fritas, já se você vai utilizar esse recurso em demazia é outra história. The ass has nothing to do with the paints, right?. :wink:

Da pra expandir o codigo que eu te mostrei em algo do tipo city.to_pointless_bag_of_properties() #=> {:cep =>’’, :name=>’’ }, mas como o proprio nome do metodo diz, isso nao faz la muito sentido.

saoj, o que tu quer fazer é programar java em Ruby.

se tu vai usar outra linguagem, siga os padrões e preceitos da linguagem nova, e não tente programar da mesma forma que fazia na linguagem anterior.
da forma que tu quer fazer ( Programar Java em Ruby ) não vai ter muitas vantagens usar Ruby.

[quote=urubatan]saoj, o que tu quer fazer é programar java em Ruby.

se tu vai usar outra linguagem, siga os padrões e preceitos da linguagem nova, e não tente programar da mesma forma que fazia na linguagem anterior.
da forma que tu quer fazer ( Programar Java em Ruby ) não vai ter muitas vantagens usar Ruby.[/quote]

Respire, conte até 10, que vc vai compreender que o que vc está falando é tendencioso ou não tem absolutamente nada haver com o tema em questão.

Recebi um objeto Cidade de um sistema desconhecido/remoto/feito pelo cliente e quero listar todas as suas propriedades via reflection. E isso não justifica essa baboseira retórica de programar em Ruby pensando em Java, Objective C, C#, Python, etc. De novo, e dessa vez em português puro, a bunda não tem nada haver com as calças.

[color=red]Descaracterizar o argumentador não descaracteriza o seu argumento,[/color] apesar de prejudicialmente desviar o foco do debate, além de ser tb indelicado.

Pq nao perguntar pra tal objeto como ele quer ser representado? Use as classes abertas e o fato de Ruby ser baseado em mensagens (e nao em metodos/propriedades) pra te ajudar, ao inves de quebrar o encapsulamento desse jeito.

Pq nao perguntar pra tal objeto como ele quer ser representado? Use as classes abertas e o fato de Ruby ser baseado em mensagens (e nao em metodos/propriedades) pra te ajudar, ao inves de quebrar o encapsulamento desse jeito.
[/quote]

Entendi que não precisamos de métodos/propriedades, mas mesmo para fazer essa "pergunta" via "mensagens" precisamos de um acordo entre as partes, certo?

Bom, estarei criando o seguinte requirimento para os objetos externos que querem ter suas propriedades visíveis ao meu sistema.


def list_props(obj)
  if obj.respond_to?(:properties)
    props = obj.send(:properties)
    props.each do |prop|
      next if not obj.respond_to?(prop)
      value = obj.send(prop)
      puts "#{prop} => #{value}"
    end
  end
end

[quote=saoj]def list_props(obj) if obj.respond_to?(:properties) props = obj.send(:properties) props.each do |prop| next if not obj.respond_to?(prop) value = obj.send(prop) puts "#{prop} => #{value}" end end end[/quote]

Faz o properties() retornar um Hash com os nomes e valores, logo. Assim vc nao fica fazendo N+1 de bobeira.

Em ruby é muito mais fácil ter contratos ad hoc. Se teu problema é o que estará acessível na view, assuma que tudo e pronto. Em vez de listar tudo, envie p/ o teu objeto somente as mensagens que a view solicitar. Simples assim.
Na view

bla bla bla #{foo}....

Em vez de listar tudo de antemão, espere precisar e só então, quando a view solicitar, envie :foo p/ teu objeto.

[quote=saoj][quote=urubatan]saoj, o que tu quer fazer é programar java em Ruby.

se tu vai usar outra linguagem, siga os padrões e preceitos da linguagem nova, e não tente programar da mesma forma que fazia na linguagem anterior.
da forma que tu quer fazer ( Programar Java em Ruby ) não vai ter muitas vantagens usar Ruby.[/quote]

Respire, conte até 10, que vc vai compreender que o que vc está falando é tendencioso ou não tem absolutamente nada haver com o tema em questão.

Recebi um objeto Cidade de um sistema desconhecido/remoto/feito pelo cliente e quero listar todas as suas propriedades via reflection. E isso não justifica essa baboseira retórica de programar em Ruby pensando em Java, Objective C, C#, Python, etc. De novo, e dessa vez em português puro, a bunda não tem nada haver com as calças.

[color=red]Descaracterizar o argumentador não descaracteriza o seu argumento,[/color] apesar de prejudicialmente desviar o foco do debate, além de ser tb indelicado.[/quote]
não estava tentando desqualificar o argumentador, toma um calmante ai e relacha, as pessoas não estão sempre querendo te agredir …
Só comentei que tu esta querendo desenvolver em Ruby utilizando os mesmos paradigmas e as mesmas soluções que tu esta acostumado a utilizar em Java.
isto é bem comum de acontecer.

se tu ler as mensagens do CV e do louds eles estão te dizendo qual a forma Ruby de se trabalhar com isto, mas tu quer por que quer fazer igual ao código java …

Eu escolhi aprender Ruby antes de Groovy exatamente para evitar de fazer isto …

[quote=urubatan]
não estava tentando desqualificar o argumentador, toma um calmante ai e relacha, as pessoas não estão sempre querendo te agredir …
Só comentei que tu esta querendo desenvolver em Ruby utilizando os mesmos paradigmas e as mesmas soluções que tu esta acostumado a utilizar em Java.
isto é bem comum de acontecer.

se tu ler as mensagens do CV e do louds eles estão te dizendo qual a forma Ruby de se trabalhar com isto, mas tu quer por que quer fazer igual ao código java …

Eu escolhi aprender Ruby antes de Groovy exatamente para evitar de fazer isto …[/quote]

Errado está você, urubatan, de insistir em dar murro contra cabeça de prego.

[quote=louds]
Errado está você, urubatan, de insistir em dar murro contra cabeça de prego.[/quote]
concordo