Méthode unique_MISSING pour tableau, hachage et gamme
-
11-12-2019 - |
Question
Je suis nouveau à Ruby.Existe-t-il un moyen d'écrire un seul "tableau defs / gamme / hachage" avec une méthode_missing qui fonctionnera pour toutes les gammes, tableaux et hachage I.e. Tous énumérables ?Par ex.Ce qui suit devrait fonctionner:
[1..5].Sum()
[1,2,3,5].Sum()
{'x' => 1, 'y' = 4}.Sum()
Somme () est notre méthode personnalisée définie méthode intérieure_missing.Dès maintenant, j'ai écrit trois fonctions différentes qui gèrent la méthode_missing pour le tableau, la plage et le hachage séparément.
La solution
You can define method_missing
for all Enumerables by opening Enumerable
module and adding an instance method to it:
module Enumerable
def method_missing *args
puts 'hi'
end
end
[].hithere # => hi
But I would recommend to define concrete sum
method (starts with lower case letter, according to Ruby methods naming guidelines) instead of adding this logic to method_missing
:
module Enumerable
def sum
# your implementation
end
end
[].sum
Autres conseils
As Alex has said the best way would be to just define your own method #sum for Enumerable, however while each Enumerable is supposed to have #each, what it yields is different for each subclass. For example Hash yields a key-value pair, which your single #sum method would have to know how to deal with.
Here's one example of how it might do it, it tries to splat the incoming arguments into an array and the sum includes only the last element of the array. This works for Hashes, Array and Ranges (however it probably only works in 1.9)
module Enumerable
def sum
r = 0
each {|(*x)| r += x.last}
r
end
end
Alternatively you could define your own iterating method for each Enumerable, like #each_for_sum and let #sum use that method to do the summing. But you'd probably have to write several versions of #each_for_sum for different Enumerables (for example, the default #each_for_sum would be just Enumerable#each, but Hash#each_for_sum would yield just values).
module Enumerable
def sum
r = 0
each_for_sum {|x| r += x}
r
end
def each_for_sum &block
each(&block)
end
end
class Hash
def each_for_sum
values.each {|x| yield x}
end
end