Devo usar alias ou alias_method?

353

Eu encontrei um post no blog aliasvs. alias_method. Como mostrado no exemplo dado nessa postagem do blog, eu simplesmente quero aliasar um método para outro dentro da mesma classe. Qual devo usar? Eu sempre vejo aliasusado, mas alguém me disse que alias_methodé melhor.

Uso de alias

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias name full_name
end

User.new.name #=>Johnnie Walker

Uso de alias_method

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias_method :name, :full_name
end

User.new.name #=>Johnnie Walker

Link de postagem do blog aqui

ma11hew28
fonte
4
Essa postagem não responde à sua pergunta?
precisa saber é o seguinte
4
@marcog: Eu li e não estou convencido. Definir aliases dentro de métodos, isso não é algo que se deve fazer com frequência.
Boris Stitnicky 3/11
2
@digitalextremist link works
lukas.pukenis
4
O guia de estilo ruby ​​agora recomenda alias"ao alternar métodos no escopo da classe lexical" e alias_method"ao alternar métodos de módulos, classes ou classes singleton em tempo de execução" github.com/bbatsov/ruby-style-guide#alias-methodividicamente
jtzero

Respostas:

380

alias_methodpode ser redefinido, se necessário. (é definido na Moduleclasse.)

aliasO comportamento da empresa muda de acordo com seu escopo e pode ser bastante imprevisível às vezes.

Veredicto: Use alias_method- oferece muito mais flexibilidade.

Uso:

def foo
  "foo"
end

alias_method :baz, :foo
Jacob Relkin
fonte
43
O que você quer dizer com imprevisível. Ingenuamente, alguém poderia dizer que a opção menos flexível será mais previsível. Além disso, você pode fornecer algum exemplo prático de como redefinir o alias_method?
Boris Stitnicky
7
exemplo de caso de uso: alias :new_method_name :old_method_nameORalias_method :new_method_name, :old_method_name
boulder_ruby 11/12/12
10
A palavra que ele procura aqui é mais resultados esperados . alias_methodé determinado no tempo de execução e não quando o código é lido, como alias, por isso, se comporta mais como esperávamos .
Joshua Pinter
4
esperar que os métodos sejam definidos dinamicamente durante o tempo de execução não é o que a maioria dos programadores espera. Pelo menos é como porcos voadores para mim.
Akostadinov
10
Alguém poderia argumentar o mesmo para defvs. define_method: " define_method. Pode ser redefinido em caso de necessidade (é definido no Module. Classe) def's comportamento muda dependendo do seu alcance e pode ser bastante imprevisível, às vezes Veredicto: Use. define_method- dá-lhe uma tonelada mais flexibilidade ".
Daniel Rikowski
62

Além da sintaxe, a principal diferença está no escopo :

# scoping with alias_method
class User

  def full_name
    puts "Johnnie Walker"
  end

  def self.add_rename
    alias_method :name, :full_name
  end

end

class Developer < User
  def full_name
    puts "Geeky geek"
  end
  add_rename
end

Developer.new.name #=> 'Geeky geek'

No caso acima, o método "name" escolhe o método "full_name" definido na classe "Developer". Agora vamos tentar com alias.

class User

  def full_name
    puts "Johnnie Walker"
  end

  def self.add_rename
    alias name full_name
  end
end

class Developer < User
  def full_name
    puts "Geeky geek"
  end
  add_rename
end

Developer.new.name #=> 'Johnnie Walker'

Com o uso do alias, o método "name" não pode escolher o método "full_name" definido no Developer.

Isso ocorre porque aliasé uma palavra-chave e seu escopo é lexicamente. Isso significa que trata selfo valor de si mesmo no momento em que o código fonte foi lido. Em contraste, alias_methodtrata selfcomo o valor determinado no tempo de execução.

Fonte: http://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html

Darme
fonte
35

Um ponto a favor de em aliasvez de alias_methodé que sua semântica é reconhecida pelo rdoc, levando a referências cruzadas na documentação gerada, enquanto o rdoc ignora completamente alias_method.

Bruno Rohée
fonte
56
Talvez o RDoc deva começar a tratar o alias_method da mesma forma que o alias. Devemos dizer-lhes sobre isso;)
Szymon Jeż
9
Como o RDoc deve entender as consequências de um método avaliado em tempo de execução?
@ user1115652 É seu ponto de vista que alguém pode ter corrigido um macaco alias_method? Isso parece realmente improvável e, se alguém fizer isso, deve estar disposto a sofrer as consequências no RDoc. Se o seu argumento é que é impossível, então por que você acha isso e como você acha que o Yardoc faz isso?
Iconoclast
35

Eu acho que existe uma regra não escrita (algo como uma convenção) que diz para usar 'alias' apenas para registrar um alias de nome de método, significa que se você deseja atribuir ao usuário do seu código um método com mais de um nome:

class Engine
  def start
    #code goes here
  end
  alias run start
end

Se você precisar estender seu código, use a meta alternativa ruby.

class Engine
  def start
    puts "start me"
  end
end

Engine.new.start() # => start me

Engine.class_eval do
  unless method_defined?(:run)
    alias_method :run, :start
    define_method(:start) do
      puts "'before' extension"
      run()
      puts "'after' extension"
    end
  end
end

Engine.new.start
# => 'before' extension
# => start me
# => 'after' extension

Engine.new.run # => start me
muito
fonte
23

Um ano depois de fazer a pergunta, chega um novo artigo sobre o assunto:

http://erniemiller.org/2014/10/23/in-defense-of-alias/

Parece que "tantos homens, tantas mentes". A partir do artigo anterior, o autor incentiva o uso alias_method, enquanto o último sugere o uso alias.

No entanto, há uma visão geral comum desses métodos nos posts do blog e nas respostas acima:

  • use aliasquando você quiser limitar o alias no escopo em que está definido
  • use alias_methodpara permitir que classes herdadas acessem
Kamil Lelonek
fonte
16

Os colaboradores da gema rubocop propõem em seu Guia de estilo Ruby :

Prefira o alias quando o método de alias no escopo da classe lexical, pois a resolução do self nesse contexto também for lexical, e ele comunica claramente ao usuário que o indireto do seu alias não será alterado no tempo de execução ou por qualquer subclasse, a menos que explicitado.

class Westerner
  def first_name
   @names.first
  end

 alias given_name first_name
end

Sempre use alias_method ao alternar métodos de módulos, classes ou classes singleton em tempo de execução, pois o escopo lexical do alias leva a imprevisibilidade nesses casos

module Mononymous
  def self.included(other)
    other.class_eval { alias_method :full_name, :given_name }
  end
end

class Sting < Westerner
  include Mononymous
end
Doktor OSwaldo
fonte
0

alias_method new_method , old_method

old_method será declarado em uma classe ou módulo que está sendo herdado agora para a nossa classe onde new_method será usado.

estes podem ser variáveis ​​ou método ambos.

Suponha que Class_1 tenha o método old e Class_2 e Class_3 herdem a Class_1.

Se a inicialização da Classe_2 ​​e da Classe_3 for feita na Classe_1, ambos poderão ter um nome diferente na Classe_2 ​​e na Classe_3 e seu uso.

Ajay
fonte