Supposons que j'ai le code suivant:

def my_test(&fn)
    #code goes here
end

my_test {
    def my_cool_fn(a, b)
        a + b
    end
}

Question : Existe-t-il un moyen, à partir du corps de my_test, d'accéder à des méthodes particulières définies par le bloc défini et transmis en tant que fn ?†< /sup>

Voici ce que j'ai essayé. J'ai été inspiré par la façon dont Struct est généralement défini :

Person = Struct.new(:name, :age) {
    def greet
        puts "Person #{name} says hello!"
    end
}
mike = Person.new("Mike", 37)
mike.greet

Je sais qu'il est possible de l'utiliser de la manière suivante pour obtenir un effet similaire à ce que je veux, mais incroyablement inélégant.

def my_test(&fn)
    ex_struct = Struct.new(:dummy, &fn)
    instance = ex_struct.new
    puts "The result is: #{instance.my_cool_fn 3, 6}"
end

my_test {
    def my_cool_fn(a, b)
        a + b
    end
}

Ce qui imprimera le The result is: 9 attendu. Cependant, cela semble un peu bidon, et je me demandais s'il y avait un moyen plus "correct" d'atteindre ce résultat.

(† Cette question est, pour mes besoins, purement hypothétique et pour le plaisir ; il n'y a pas de problème plus important que j'essaie de résoudre, j'essaie juste d'en apprendre plus sur cette langue.)

0
Conor O'Brien 16 nov. 2020 à 12:58

1 réponse

Meilleure réponse

Ruby est un langage orienté objet. Chaque méthode doit être définie sur quelque chose (un objet). Vous devez choisir où vous souhaitez définir cette méthode.

Vous pouvez le définir sur le même objet my_test est actuellement défini (main) en évaluant simplement le bloc.

def my_test(&fn)
  instance_eval(&fn)
end

my_test {
  def my_cool_fn(a, b)
    a + b
  end
}

my_cool_fn(1,2) #=> 3

Ou vous pouvez utiliser une nouvelle classe/module (par exemple Struct) et le définir comme vous l'avez fait.

2
Siim Liiser 16 nov. 2020 à 10:51