Esta é toda a linha de código? Quero dizer, não há nada antes de 'enviar'?
girafa
Respostas:
107
send envia uma mensagem para uma instância de objeto e seus ancestrais na hierarquia de classes até que algum método reaja (porque seu nome corresponde ao primeiro argumento).
Na prática, essas linhas são equivalentes:
1.send'+',21.+(2)1+2
Observe que sendignora as verificações de visibilidade, para que você também possa chamar métodos privados (útil para teste de unidade).
Se não houver realmente nenhuma variável antes de enviar, isso significa que o objeto global é usado:
Ah, entendo, então pode-se usar send se quiser armazenar algo como 1 mês no banco de dados em vez de dizer estaticamente o número de dias.
Christian Bankester
3
É verdade que você pode usá-lo para chamar métodos com nomes que são calculados, não estáticos. (Você não deve permitir entrada irrestrita do usuário, no entanto, para evitar a chamada de métodos privados ... Você poderia, no entanto, dar a eles um prefixo exclusivo: send 'user_method _' + methodname, * args)
giraff
2
Um bom caso de uso pode ser quando você deseja testar um método de classe protegida, você pode chamá-lo fora de uma classe - no arquivo de teste ..
GN.
106
send é um método ruby (sem rails) que permite invocar outro método pelo nome.
Ótima resposta, mais clara do que a resposta verbosa aceita.
codificação aaron de
63
Um dos recursos mais úteis que eu acho com o método .send é que ele pode chamar o método dinamicamente. Isso pode economizar muito tempo de digitação. Um dos usos mais populares do método .send é atribuir atributos dinamicamente. Por exemplo:
classCar
attr_accessor :make,:model,:year
end
Para atribuir atributos regularmente, seria necessário
c =Car.new
c.make="Honda"
c.model="CRV"
c.year="2014"
Usar .send dessa maneira adiciona complexidade desnecessária e torna mais fácil introduzir inadvertidamente um bug no código. Por exemplo, no código acima, se você adicionar uma nova entrada ao hash de parâmetros (como 'cilindros'), o código falhará com um erro de método indefinido.
Kevin Schwerdtfeger
1
respond_to? pode ser usado para prevenir tais erros, se desejado.
Richard_G
1
Essa foi uma ótima explicação! Obrigado Jha!
Sharath
1
@Kevin você está certo, mas às vezes pode ser necessário. Mais flexibilidade está relacionada a mais riscos, que podem ser mitigados.
Obrigado! Essa é exatamente a resposta que procuro. Quer saber se isso é comumente usado? Encontrei algo semelhante no código legado, não tenho certeza se devo continuar com ele. @ Mike Vallano
B Liu
1
@ b-liu Já vi isso ser usado por desenvolvedores experientes em novos códigos. Também pode ser útil ao usar define_method: apidock.com/ruby/Module/define_method .
Mike Vallano
Impressionante! Muito obrigado! @MikeVallano
B Liu
4
O que enviar faz?
send é outra maneira de chamar um método.
Isso é melhor ilustrado por um exemplo:
o =Object.new
o.send(:to_s)# => "#<Object:0x00005614d7a24fa3>"# is equivalent to:
o.to_s # => "#<Object:0x00005614d7a24fa3>"
O benefício dessa abordagem é que você pode passar o método que deseja chamar como um parâmetro. Aqui está um exemplo simples:
def dynamically_call_a_method(name)
o =Object.new
o.send name
end
dynamically_call_a_method(:to_s)# => "#<Object:0x00005614d7a24fa3>"
Você pode passar o método que deseja ser chamado. Neste caso, passamos :to_s. Isso pode ser muito útil ao fazer a metaprogramação do Ruby, porque nos permite chamar diferentes métodos de acordo com nossos diferentes requisitos.
Respostas:
send
envia uma mensagem para uma instância de objeto e seus ancestrais na hierarquia de classes até que algum método reaja (porque seu nome corresponde ao primeiro argumento).Na prática, essas linhas são equivalentes:
Observe que
send
ignora as verificações de visibilidade, para que você também possa chamar métodos privados (útil para teste de unidade).Se não houver realmente nenhuma variável antes de enviar, isso significa que o objeto global é usado:
fonte
send é um método ruby (sem rails) que permite invocar outro método pelo nome.
Da documentação
http://corelib.rubyonrails.org/classes/Object.html#M001077
fonte
Um dos recursos mais úteis que eu acho com o método .send é que ele pode chamar o método dinamicamente. Isso pode economizar muito tempo de digitação. Um dos usos mais populares do método .send é atribuir atributos dinamicamente. Por exemplo:
Para atribuir atributos regularmente, seria necessário
Ou usando o método .send:
Mas tudo pode ser substituído pelo seguinte:
Assumindo que seu aplicativo Rails precisa atribuir atributos à classe do seu carro a partir da entrada do usuário, você pode fazer
fonte
Outro exemplo, semelhante ao https://stackoverflow.com/a/26193804/1897857 de Antonio Jha
é se você precisa ler atributos em um objeto.
Por exemplo, se você tiver um array de strings, se tentar iterar por meio deles e chamá-los em seu objeto, não funcionará.
No entanto, você pode
send
inserir as strings no objeto:fonte
define_method
: apidock.com/ruby/Module/define_method .O que enviar faz?
send
é outra maneira de chamar um método.Isso é melhor ilustrado por um exemplo:
Envie vidas na classe Object .
Qual é o benefício disso?
O benefício dessa abordagem é que você pode passar o método que deseja chamar como um parâmetro. Aqui está um exemplo simples:
Você pode passar o método que deseja ser chamado. Neste caso, passamos
:to_s
. Isso pode ser muito útil ao fazer a metaprogramação do Ruby, porque nos permite chamar diferentes métodos de acordo com nossos diferentes requisitos.fonte
Outro caso de uso para visualizações:
Permitir . você deve escrever uma visão escalonável que trabalha com todos os tipos de objetos com:
fonte