Чи слід використовувати псевдонім або alias_method?


353

Я знайшов в блозі на aliasVS. alias_method. Як показано в прикладі, наведеному в цій публікації блогу, я просто хочу псевдонімувати метод іншому в тому ж класі. Який я повинен використовувати? Я завжди бачу aliasвживаного, але хтось сказав мені alias_method, що краще.

Використання псевдоніма

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias name full_name
end

User.new.name #=>Johnnie Walker

Використання alias_method

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias_method :name, :full_name
end

User.new.name #=>Johnnie Walker

Посилання на щоденник тут


4
Чи не відповідає цей пост на ваше запитання?
moinudin

4
@marcog: Я прочитав це, і не переконаний. Визначаючи псевдоніми всередині методів, це не те, що потрібно робити часто.
Boris Stitnicky

2
@digitalextremist посилання працює
lukas.pukenis

4
Посібник зі стилю рубіну тепер рекомендує alias"при згладжуванні методів в області лексичного класу" та alias_method"при згладжуванні методів модулів, класів або класів синглів
jtzero

Відповіді:


380

alias_methodпри необхідності можна переробити (визначено в Moduleкласі.)

aliasПоведінка змінюється залежно від сфери її застосування і може бути часом непередбачуваною.

Вердикт: Використовуйте alias_method- це дає тоні більше гнучкості.

Використання:

def foo
  "foo"
end

alias_method :baz, :foo

43
Що ви маєте на увазі під непередбачуваним. Наївно, можна сказати, що менш гнучкий варіант буде більш передбачуваним. Крім того, чи можете ви надати будь-який практичний приклад користі від переосмислення alias_method?
Boris Stitnicky

7
Приклад використання випадку: alias :new_method_name :old_method_nameАБОalias_method :new_method_name, :old_method_name
boulder_ruby

10
Слово, яке він шукає тут, - це більш очікувані результати. alias_methodвизначається під час виконання, а не тоді, коли код читається, як alias, отже, він веде себе більше так, як ми би його очікували .
Джошуа Пінтер

4
очікуючи, що методи визначаються під час руху під час виконання - це не те, чого очікують більшість програмістів. Принаймні, це як до мене летять свині.
акостадінов

10
Можна сказати те саме, що і defпроти define_method: " define_methodможна переосмислити, якщо це потрібно. (Це визначено в Moduleкласі.) defПоведінка змінюється залежно від сфери її застосування і може бути часом непередбачуваною. Вердикт: Використання define_method- це дає тону більша гнучкість ".
Даніель Ріковський

62

Крім синтаксису, основна відмінність полягає в оцінці :

# 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'

У наведеному вище випадку метод "ім'я" вибирає метод "full_name", визначений у класі "Developer". Тепер давайте спробуємо 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'

З використанням псевдоніма метод "name" не в змозі вибрати метод "full_name", визначений в Developer.

Це тому alias, що це ключове слово, і воно лексично охоплено. Це означає, що воно трактує selfяк значення "self" під час читання вихідного коду. На відміну від них, alias_methodтрактується selfяк значення, визначене під час виконання.

Джерело: http://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html


35

Справа aliasзамість цього alias_methodполягає в тому, що його семантика розпізнається rdoc, що призводить до акуратних посилань у створеній документації, тоді як rdoc повністю ігнорує alias_method.


56
Можливо, RDoc повинен почати обробляти alias_method так само, як псевдонім. Ми мусимо розповісти їм про це;)
Szymon Jeż

9
Як RDoc повинен розуміти наслідки методу, який оцінюється під час виконання?

@ user1115652 Ваша думка, що хтось, можливо, зафіксував мавпу alias_method? Це здається насправді малоймовірним, і якщо хтось це зробить, то вони повинні бути готові понести наслідки в RDoc. Якщо ваша думка полягає в тому, що це неможливо, то чому ви вважаєте це і як ви думаєте, як це робить Ярдок?
іконоборство

35

Я думаю, що існує неписане правило (щось на зразок конвенції), яке говорить, що використовувати "псевдонім" лише для реєстрації псевдоніма імені методу, означає, якщо ви хочете надати користувачеві свого коду один метод з більш ніж одним ім'ям:

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

Якщо вам потрібно розширити свій код, використовуйте мета-альтернативу 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

23

Через рік після запитання з'являється нова стаття на цю тему:

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

Здається, «стільки чоловіків, стільки розумів». З першої статті автор рекомендує використовувати alias_method, а другий пропонує використовувати alias.

Однак загальний огляд цих методів є як у позах для блогів, так і у відповідях вище:

  • використовувати, aliasколи ви хочете обмежити псевдонім на область, де це визначено
  • використовувати, alias_methodщоб дозволити спадковим класам отримати доступ до нього

16

Співробітники дорогоцінних каменів rubocop пропонують у своєму керівництві про стиль Ruby :

Віддайте перевагу псевдоніму, коли методи псевдоніму в області лексичного класу, як роздільна здатність "Я" в цьому контексті, також є лексичними, і він чітко повідомляє користувачеві, що опосередкованість вашого псевдоніма не буде змінена під час виконання або будь-яким підкласом, якщо не буде зроблено явно.

class Westerner
  def first_name
   @names.first
  end

 alias given_name first_name
end

Завжди використовуйте alias_method під час випробовування методів модулів, класів або однокласних класів під час виконання, оскільки лексична область псевдоніму призводить до непередбачуваності в цих випадках

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

class Sting < Westerner
  include Mononymous
end

0

alias_method new_method , old_method

old_method буде оголошений у класі або модулі, який зараз успадковується нашому класу, де буде використовуватися new_method .

вони можуть бути змінними або методом обох.

Припустимо, у Class_1 є old_method, а Class_2 і Class_3 вони успадковують Class_1.

Якщо ініціалізація Class_2 та Class_3 проводиться у Class_1, то обидва можуть мати різні назви в Class_2 та Class_3 та їх використання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.