Invocando a chamada () numa função em Ruby
Tenho o seguinte código:
def sum(a, b)
a + b
end
puts sum.call 2, 3
Tenho um erro do tipo:
wrong number of arguments (given 0, expected 2) (ArgumentError)
Como posso chamar uma função?
EDITAR
Quero ter uma função capaz de chamar outra com certos argumentos. Eu escrevi o código como abaixo, mas o mesmo erro ainda é exibido.def sum(a, b)
a + b
end
def kall(func, *args)
send(func, *args)
end
puts kall(sum, 2, 3)
3 answers
Para invocar a função sum
, basta apagar a chamada .call
:
def sum(a, b)
a + b
end
sum(1, 2)
# => 3
Outra maneira de chamar o método é fazer:
send(:sum, 1, 2)
Que invoca o método sum
no contexto/objecto actual com a lista de argumentos (1, 2).
Mais uma maneira de chamar um método é:
method(:sum).call(2, 3)
#=> 5
sum
não é uma função,é um método . Os métodos pertencem a objectos, eles não são objectos. Ruby é uma linguagem orientada a objetos, o que significa que você só pode armazenar objetos em variáveis, só passar objetos como argumentos (com a exceção ligeiramente estranha de blocos), só retornar objetos de métodos e apenas enviar mensagens para objetos.
Você não pode enviar uma mensagem para o método sum
, porque você só pode enviar mensagens para objetos, e os métodos não são objecto.
E mesmo que fosse possível enviar mensagens para métodos, ainda haveria uma ambiguidade no seu código: o Ruby permite-lhe deixar de fora a lista de argumentos para uma mensagem enviada Se não passar quaisquer argumentos, por isso
sum
É uma mensagem válida enviada e é (um pouco) equivalente (Privacidade modulo) a
self.sum()
Então, mesmo se fosse possível enviar mensagens para os métodos, Ruby aindapensaria que você tenta enviar o sum
mensagem sem uma lista de argumentos.
Proc
s. Uma solução seria usar um Proc
em vez de um método:
sum = -> (a, b) { a + b }
sum.(2, 3)
#=> 5
A outra solução seria obter um objecto para o método. O sistema de reflexão da Ruby tem um classe chamada Method
o que responde a call
, exemplos dos quais são proxies reflexivos para métodos. Você pode obter um objeto Method
enviando o Object#method
mensagem para um objecto, por exemplo:
sum = method(:sum)
sum.(2, 3)
#=> 5