Hash vers un objet

Bonjour,

Existe-t-il une fonction qui permettrait de faire des choses comme.

J’ai une hash : options[:title] = ‘Bienvenue sur …’

Et j’aimerais transformer cela pour pouvoir faire des choses comme

options.title pour accèder à options[:title] qui est plus joli :stuck_out_tongue:

Merci beaucoup,

Pierre

c’est un meilleur titre :wink:

Je ne suis pas sûr que ce soit une très bonne idée, étant donné qu’un
hash
peut prendre n’importe quoi comme clef primaire, entiers, chaînes de
caractères, objets, etc. et pas seulement des gentils symboles faciles Ã
transformer en nom de méthode.

Une solution médiane qui me semble être pas trop pénible à la longue
pourrait être de faire un objet qui ait des méthodes : [] et []=, qui
n’accepte que des symbolizables comme clef (méthode to_sym qui réponde),
et
qui envoie les calls à méthodes non définies en les renvoyant à [] ou
[]=
quand c’est possbile.

Ceci dit, ça me semble limite laid, et je ne vois d’ailleurs pas
tellement
bien en quoi la syntaxe à point te plait tellement, ou pourquoi tu ne
travailles pas tout bêtement avec un objet plutôt qu’un hash ?


Michel B.

Je ne suis pas sûr que ce soit une très bonne idée, étant donné qu’un
hash
peut prendre n’importe quoi comme clef primaire, entiers, chaînes de
caractères, objets, etc. et pas seulement des gentils symboles faciles Ã
transformer en nom de méthode.

Une solution médiane qui me semble être pas trop pénible à la longue
pourrait être de faire un objet qui ait des méthodes : [] et []=, qui
n’accepte que des symbolizables comme clef (méthode to_sym qui réponde),
et
qui envoie les calls à méthodes non définies en les renvoyant à [] ou
[]=
quand c’est possbile.

Ceci dit, ça me semble limite laid, et je ne vois d’ailleurs pas
tellement
bien en quoi la syntaxe à point te plait tellement, ou pourquoi tu ne
travailles pas tout bêtement avec un objet plutôt qu’un hash ?

(évite de prendre l’habitude de dupliquer les messages sur une mailing
list,
ce n’est pas comme un forum…)


Michel B.

Bonjour,

Pas super élégant à mon avis mais tu peux utiliser Struct et l’opérateur
“splat” pour faire ça :

Hash de départ

infos = {:name => ‘Mon nom’, :age => 30, :male? => true}

Construction de la classe à partir des clés de la Hash

Customer = Struct.new(*infos.keys)

Instanciation de la classe créée avec les valeurs contenues dans la

Hash
a_customer = Customer.new(*infos.values)

Tests

a_customer.name

=> “Mon nom”

a_customer.age

=> 30

Attention aux noms d’attributs un peu spéciaux

a_customer.male?

=> NoMethodErreor

a_customer[:male?]

=> true

Stéphane.
2008/9/22 Pierre V. [email protected]

On Mon, Sep 22, 2008 at 11:51, Pierre V. [email protected]
wrote:

Merci beaucoup,

Je sais que ca existe et qu’il s’agit d’une fonction passant dans
toutes les clés du hash pour en faire des fonctions, mais je ne me
rapelle plus du nom, ni si ca appartient a rails ou ruby.


http://fabien.jakimowicz.com

Fabien J. a écrit :

Merci beaucoup,

Je sais que ca existe et qu’il s’agit d’une fonction passant dans
toutes les clés du hash pour en faire des fonctions, mais je ne me
rapelle plus du nom, ni si ca appartient a rails ou ruby.

Configatron : http://configatron.mackframework.com/
Fait plus cela mais dans le but de conserver des paramètres (avec un
singleton
donc).

Regarde (ou utilise) la classe OrderedOptions qui utilise method_missing.

Un exemple vaut mieux qu’un long baratin:

class Setting < HashWithIndifferentAccess
def method_missing(method)
key?(method) ? self[method] : super
end
end

s = Setting.new({:toto => ‘1’, ‘tata’ => 2, ‘key?’ => ‘tata’})

s.toto
=> “1”

s.tata
=> 2

Avec les drawbacks
#method qui existe déjÃ

s.key?
ArgumentError: wrong number of arguments (0 for 1)
from (irb):11:in `key?’
from (irb):11

#clée absente

s.not_a_key
NoMethodError: undefined method not_a_key' for Settings from /Users/nel/ruby/feedback/vendor/heywatch-0.0.1/lib/heywatch/ ext.rb:46:inmethod_missing’
from (irb):3:in `method_missing’
from (irb):12

Merci à tous pour vos réponses

C’est quand même génial Ruby :wink:

On 22 sep, 15:45, “Renaud (Nel) Morvan” [email protected]

2008/9/22 Pierre :

Existe-t-il une fonction qui permettrait de faire des choses comme.

J’ai une hash : options[:title] = ‘Bienvenue sur …’

Et j’aimerais transformer cela pour pouvoir faire des choses comme

options.title pour accèder à options[:title] qui est plus joli :stuck_out_tongue:

Regarde (ou utilise) la classe OrderedOptions qui utilise
method_missing.

– Jean-François.


ça dépend
http://twitter.com/underflow_

Le 22 septembre 2008 15:45, Renaud (Nel) Morvan a écrit :

Regarde (ou utilise) la classe OrderedOptions qui utilise method_missing.

Un exemple vaut mieux qu’un long baratin:

Ma réponse en une seule phrase me semblait pourtant faire preuve de
concision.

class Setting < HashWithIndifferentAccess
def method_missing(method)
key?(method) ? self[method] : super
end
end

à comparer avec OrderedOptions#method_missing :

def method_missing(name, args)
if name.to_s =~ /(.
)=$/
self[$1.to_sym] = args.first
else
self[name]
end
end

qui traite de #toto=

Avec les drawbacks
#method qui existe déjà
#clée absente

Ouais.

– Jean-François.


ça dépend

http://pastie.org/278407

The solution is packed into a module so that you can do something like
this:

hash = HashWithIndifferentAccess.new
hash.extend(HashMethodAccessors)

or:

class MySuperCoolHash < HashWithIndifferentAccess
include HashMethodAccessors
end

hash = MySuperCoolHash.new

In other words: it is not hard-coded with HashWithIndifferentAccess or
just a Hash or whatever class you use as a hash.