Войти на сайт

Авторизация, ждите ...
×

ТЕМА: aliases

aliases 9 года 8 мес. назад #72754

  • Iren_Rin
  • Iren_Rin аватар
  • Вне сайта
  • Мастер
  • Сообщений: 247
  • Спасибо получено: 537
  • КоммерсантПроект года 1 местоПроект месяца 1 местоПрограммист RubyУчитель
Не нашел такой темы, а тема важная, для мейкера. Для скриптеров со стажем это наверное будет не очень интересно.
И так, что такое alias - в руби это просто напросто ссылка на метод, когда вы хотите чтобы ваш метод отзывался и на другое (третье, четвертое...) имя.
class Fireblast
  def damage
    100
  end
 
  alias dmg damage
end
 
spell = Fireblast.new
spell.damage #=> 100
spell.dng    #=> 100
Алиасы можно объявить при помощи alias и alias_method. Первый является ключевым словом, и может принимать в себя имена методов как есть (не строки и не символы, а просто имена), второй - приватный метод объектов Class / Module, он принимает строки \ символы, разделенные запятыми (как обычный метод).
В обоих случаях первым следует передовать имя нового метода, вторым - имя оригинала.
class Fireblast
 def cast_time
   1
 end
 
 alias_method :delay, :cast_time
end
Допустим есть у вас в мейкере класс Fireblast, допустим вы хотите внести в его изменения: хотите чтобы он кроме урона делал еще что нибудь (выводил сообщение на STDOUT для примера.) Как это сделать? Первый способ - и самый плохой по совместительству - это найти этот класс \ метода и все исправить на месте. Если будете так делать в итоге что нибудь сломаете в оригинальных скриптах и будете долго думать, как все починить. Второй - использовать возможность руби переопределять код налету, и написать в новом скрипте (сделать патч) как-нибудь так:
class Fireblast
  def damage
    puts 'Fireblast#damage called'
    100
  end
end
Это будет работать, но вы только что сделали дубликат кода - цифра 100 встречается в двух местах - в оригинальном методе, и в вашем патче. Это особо не страшно если вам нужно только одну строчку дублировать. А если их там с десяток? Тогда лучше использовать такую странную особенностью руби как alias chain. Суть в том, что когда вы делаете алиас при помощи alias (alias_method) руби на саом деле копирует метод, а не просто добавляет ссылку. Это неприятно на первый взгляд, зато позволяет делать так:
class Fireblast
  alias original_cast_time cast_time #мы сделали копию cast_time и назвали ее orignal_cast_time
   
  def cast_time #переопределяем метод cast_time
    puts "Fireblast#cast_time called" # добовляем новый функционал
    original_cast_time                # вызываем старый метод
  end
end
 
spell = Fireblast.new
spell.cast_time #=> выведет на STDOUT сообщение и вернет 1
Многие скрипты, которые модифицируют методы оригинальных классов, делают это именно так.

Так же объясню как делать алиасы к методам модуля.
Модуль можно использовать двумя способами, первый способ - когда нужно подмешать (Mixin) методы в свой класс:
module Words
  def  bye
    puts 'good bye'
  end
end
 
class Test
  include Words
end
 
Test.new.bye #выведет на STDOUT good bye

Допустим вы хотите сделать alias chain для этого модуля. Вы можете сделать это так же как и для классов:
module Words
  alias original_bye bye
 
  def bye
    puts "I say you"
    original_bye
  end
end
Test.new.bye #выведет два сообщения на STDOUT

Но гораздо лучше использовать стандартное наследование:
class Test
  include Words
 
  def bye
    puts "I say you"
    super #это работает как для классов, так и для модулей, подключенных через include
  end
end
 
Tew.new.bye #выведет все так же две строки на STDOUT

Так же модуль можно использовать как контейнер для функций (у меня ниразу не было надобности использовать модули так, я всегда находил повод сделать класс)
module Words
  def self.greetings
    puts 'hello'
  end
end
Words.greetings #выведет hello на STDOUT
И когда вы хотите сделать alias chain для такой функции начинаются интересные дела. Есть несколько способов это сделать, больше всего мне нравится такой:
module Words
  instance_eval do
    alias original_greetings greetings
 
    def greetings
      puts 'I say you'
      original_greetings
    end
  end
end
Words.greetings #выведет 2 строки на STDOUT
Что такое instance_eval я обязательно расскажу, когда буду говорить о метапрограммировании.

Тут информация о том как это нужно делать в руби 2.1.2. Алиасы там все еще работают так же, как и в ранних версиях, но появился путь, значительно более прозрачный.

ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ]
Последнее редактирование: 9 года 7 мес. назад от Iren_Rin.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: DeadElf79, strelokhalfer, Lipton, Amphilohiy, yuryol, MaltonTheWarrior, DesKarD, VarVarKa

aliases 9 года 8 мес. назад #72756

  • DeadElf79
  • DeadElf79 аватар
  • Вне сайта
  • Звездный Страж
  • Сообщений: 3147
  • Спасибо получено: 2650
  • 1 место в ГотвВетеранУчительПрограммист RubyПроект месяца 2 место3 местоОрганизатор конкурсовПисатель 3 местоПроект месяца 1 место
собственно, да, наконец-то отдельная тема. а то я свою так и не вытащил из обсуждения, да)
спасибо, кстати, не знал разницы между alias и alias_method и всегда использовал только первый ^_^
Администратор запретил публиковать записи гостям.

aliases 9 года 8 мес. назад #72757

  • Amphilohiy
  • Amphilohiy аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 547
  • Спасибо получено: 666
  • Победитель Сбитой кодировкиУчитель2 место ГотвПрограммист RubyОратор
Буквально один из первых вопросов, с которым я влетел на этот форум - как алиасить модули? Добавь и эту плюшечку, будет полезно.
ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ]
Я верю, что иногда компьютер сбоит, и он выдает неожиданные результаты, но остальные 100% случаев это чья-то криворукость.
Администратор запретил публиковать записи гостям.

aliases 9 года 8 мес. назад #72760

  • DeadElf79
  • DeadElf79 аватар
  • Вне сайта
  • Звездный Страж
  • Сообщений: 3147
  • Спасибо получено: 2650
  • 1 место в ГотвВетеранУчительПрограммист RubyПроект месяца 2 место3 местоОрганизатор конкурсовПисатель 3 местоПроект месяца 1 место
кстати, про заметку амфилохия - что это значит и зачем оно нужно? класс под модулем, хм..?
Администратор запретил публиковать записи гостям.

aliases 9 года 8 мес. назад #72761

  • Amphilohiy
  • Amphilohiy аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 547
  • Спасибо получено: 666
  • Победитель Сбитой кодировкиУчитель2 место ГотвПрограммист RubyОратор
DeadElf79 пишет:
кстати, про заметку амфилохия - что это значит и зачем оно нужно? класс под модулем, хм..?
Врыв в объект как в одиночку. Так, например, можно поменять метод уже существующего объекта с существующим классом, не меняя остальные. Если позволите, ссылка на stackoverflow.com.
Я верю, что иногда компьютер сбоит, и он выдает неожиданные результаты, но остальные 100% случаев это чья-то криворукость.
Администратор запретил публиковать записи гостям.

aliases 9 года 8 мес. назад #72762

  • Iren_Rin
  • Iren_Rin аватар
  • Вне сайта
  • Мастер
  • Сообщений: 247
  • Спасибо получено: 537
  • КоммерсантПроект года 1 местоПроект месяца 1 местоПрограммист RubyУчитель
Я внесу добавление в тему вечером. Если в кратце это способ добавить алиасы к методом модуля (к тем что определены через self). Согласен, оно немного сбивает с толку, лучше все таки использовать instance_eval {}
Администратор запретил публиковать записи гостям.

aliases 9 года 7 мес. назад #72813

  • Iren_Rin
  • Iren_Rin аватар
  • Вне сайта
  • Мастер
  • Сообщений: 247
  • Спасибо получено: 537
  • КоммерсантПроект года 1 местоПроект месяца 1 местоПрограммист RubyУчитель
Добавил про модули в первый пост.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: DeadElf79, Amphilohiy

aliases 8 года 2 мес. назад #90060

  • DesKarD
  • DesKarD аватар
  • Вне сайта
  • Заблокирован
  • Очередной шутнечок...
  • Сообщений: 300
  • Спасибо получено: 190
В общем прочёл статью, вроде понял.
Как начинаю пробовать прочитанное запечатлеть в код ничего не выходит.
class Game_Event < Game_Character
  alias new_update_self_movement update_self_movement
    if @stop_count > stop_count_threshold
    end
end 

Ошибка [ Нажмите, чтобы развернуть ]


Куда я не так пихаю?
Золотой сборник цитат Светлой [ Нажмите, чтобы развернуть ]

Помогите Юриолю потушить его попчанский [ Нажмите, чтобы развернуть ]
Последнее редактирование: 8 года 2 мес. назад от DesKarD.
Администратор запретил публиковать записи гостям.

aliases 8 года 2 мес. назад #90061

  • Волчонок
  • Волчонок аватар
  • Вне сайта
  • Просветлённый
  • Волчонок
  • Сообщений: 277
  • Спасибо получено: 247
  • 2 место 3 место3 место в КодировкеОрганизатор конкурсов
DesKarD пишет:
stop_count_threshold

У тебя эта переменная нигде в теле функции не определена. Или я чего-то не помню.
DesKarD пишет:
Куда я не так пихаю?

#янепошлый
Ленивый волчонок с большими амбициями

Рассказ "Рождение мага", периодически обновляется
РПГ История Егеря. Основной текущий проект.

ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ]
Администратор запретил публиковать записи гостям.

aliases 8 года 2 мес. назад #90063

  • Cerberus
  • Cerberus аватар
  • Вне сайта
  • Модератор
  • Собака злая
  • Сообщений: 2269
  • Спасибо получено: 1182
  • Организатор конкурсовПрограммист JavaScript Проект месяца 3 место2 место Проект месяца 2 место3 место ГотвПроект месяца 1 место3 местоПисатель 3 место2 место Сбитая кодировка
Начнём с того, что этот код ничего не переопределяет. Он только делает копию события и задаёт условие, при котором что-то могло бы быть сделано, но, так как в момент проверки условия (т.е. при создании класса, до начала работы основной программы) переменная @stop_count не инициализирована - условие бессмысленно. Продолжим - да, тем, что забывать про @ нельзя, @stop_count_treshold и stop_count_treshold - это две абсолютно разные вещи.
Жуть болотная, на лапках, в тапках и с пулемётом...
Администратор запретил публиковать записи гостям.

aliases 8 года 2 мес. назад #90068

  • DeadElf79
  • DeadElf79 аватар
  • Вне сайта
  • Звездный Страж
  • Сообщений: 3147
  • Спасибо получено: 2650
  • 1 место в ГотвВетеранУчительПрограммист RubyПроект месяца 2 место3 местоОрганизатор конкурсовПисатель 3 местоПроект месяца 1 место
Дес, я специально на этот случай расписывал более просто, держи: rpg-maker.info/forum/fakultet-skriptov/6...nie-protivnika#89910 Прочти и сделай по примеру ^_^
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: DesKarD
Время создания страницы: 0.716 секунд