j'ai un script relativement simple, qui en fonction d'un paramètre utilisateur va appliquer telle ou telle mesure.
Les mesures s'appliquent sur les mêmes valeurs, mais ne les prennent pas en compte de la même façon. Je voudrais faire un code propre qui associe la mesure choisie par l'utilisateur (par exemple "mi" ou "log") à un identificateur (par exemple "my_measure") pour ensuite appeler de façon transparente "my_measure(a,b,c,d,n)".
En perl, il me semble que ça s'appelle un pointeur de fonction. Quelque part dans le code on aura :
$my_measure = \&mi ;
ou
$my_measure = \&log ;
en fonction du choix de l'utilisateur (avec un case, mais probablement avec un truc super gruik parce que c'est du perl).
puis
&$my_measure(a,b,c,d,n)
Je n'arrive pas à faire la même chose en ruby. J'ai trouvé des pistes (à coup de Proc.new) mais j'avoue ne rien y comprendre, et que je trouve ça hardcore pour le simple petit problème que j'ai (du coup je me dis que les réponses ne correspondent pas à ma question).
Cher forum, aurais-tu une idée ?
# .call
Posté par Kerro . Évalué à 2.
def ma_fonction()
blablabla # je ne sais toujours pas faire les indentations entre les balises < code >
end
ma_fonction.call
[^] # Re: .call
Posté par Duncan Idaho . Évalué à 1.
J'ai plusieurs fonctions (des exemples jouets ici) :
def mi(a,b,c,d)
return a*b*c*d
end
def log(a,b,c,d)
return a/b/c/d
end
J'ai un paramètre, "mes" et je fais
case mes
when "mi"
my_function = mi # mais ça marche pas comme ça
when "log"
my_function = log # mais ça marche pas comme ça
end
et je voudrais qu'un appel à "my_function(a,b,c,d)" appelle log(a,b,c,d) ou mi(a,b,c,d) en fonction du choix du case.
J'ai trouvé une solution qui me paraît un peu gruik.
class MesMesures
def mi(a,b,c,d)
...
end # mi
def log(a,b,c,d)
...
end # log
end # class MesMesures
[...]
all_func = MesMesures.new
case mes
when "mi"
ma_fonction = all_func.method( :mi )
when "log"
ma_fonction = all_func.method( :log )
end
...
ma_fonction.call(a,b,c,d) # fonctionne !
[^] # A corriger
Posté par Kerro . Évalué à 2.
Sinon: http://www.ruby-doc.org/docs/ProgrammingRuby/html/ospace.htm(...)
[^] # on est bien vendredi
Posté par beb . Évalué à 3.
when "mi"
my_function = mi # mais ça marche pas comme ça
en python, ca marche bien comme ca :) ---> []
[^] # Re: on est bien vendredi
Posté par Kerro . Évalué à 2.
call eax
1 instruction, 7 caractères. Quelqu'un a plus court ? :-)
[^] # Re: .call
Posté par Jean B . Évalué à 1.
class Functions
def self.foo(a, b, c)
end
def self.bar(a, b, c)
end
end
func_name = "bar"
if Functions.respond_to? func_name
Functions.method(func_name).call('a', 'b', 'c')
end
[^] # Re: .call
Posté par benoar . Évalué à 4.
Je dis ça parce que je fais du python, et qu'on me vante souvent ruby comme un langage encore mieux, blah blah. Si on n'est pas capable de résoudre sont problème simplement, il y a vraiment un gros problème.
Solution en python, sans classe ni trop de bordel :
def mi(a, b, c, d):
return a*b*c*d
def log(a, b, c, d):
return a/b/c/d
Puis :
if mes == "mi":
ma_fonction = mi
elif mes == "log":
ma_fonction = log
Voire :
ma_fonction = locals()[mes]
(ok, l'utilisation de locals() est crade)
Et on peut ainsi utiliser :
ma_fonction(1,2,3,4)
Tout simplement.
Donc s'il y a des spécialistes de ruby dans le coin, vous pouvez me dire s'il n'y a vraiment pas de first-class function en ruby ? Ou alors justement c'est qu'il n'y a aucun spécialiste ruby sur ce thread ?
(ne le prenez pas méchamment, c'est juste que j'hallucine grave sur cette lacune si c'en est vraiment une)
[^] # Re: .call
Posté par Jean B . Évalué à 4.
Pour obtenir le même effet il faut utiliser la "buit-in" method, et ensuite pour l'appeler il faut utiliser la méthode call.
#python
func = locals()[func_name]
func(1, 2, 3)
#ruby
func = method(func_name)
func.call(1, 2 , 3)
Mais cet exemple que ce soit en python ou en ruby est a éviter car si j'ai bien suivi le nom de la fonction viens d'une saisie utilisateur. Il vaut donc mieux isoler les fonctions disponibles dans un espace de nom (une classe) car si par un hasard soudain func_name == 'exit' ben ...
[^] # Re: .call
Posté par benoar . Évalué à 2.
# send et method/call
Posté par Arnaud Taffanel . Évalué à 2.
my_function="mi"
send(my_function,1,2,3,4);
my_function=:log
send(my_function,1,2,3,4)
Ou avec method et call cité plus haut :
my_function = method(:mi)
my_function.call(1,2,3,4)
my_function = method("log")
my_function.call(1,2,3,4)
Dans les deux cas on peu utiliser une chaine de carractere ou un symbole (:mi ou :log). J'imagine qu'avec un symbole le code doit etre plus performant, cela dit je n'en suis pas sur.
Comme en ruby la ligne de code "my_function(1,2,3,4)" serais equivalent à "self.send(:my_function,1,2,3,4)" je ne crois pas qu'il existe de solution où l'on puisse appeler "my_function(1,2,3,4)" comme on le ferais avec un pointeur de fonction en C par exemple.
Cordialement.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.