Войти на сайт

Авторизация, ждите ...
×
Правила раздела:
1 Задавайте конкретные вопросы. Для болтовни есть свободный раздел.
2 По возможности давайте конкретные ответы.
3 Один вопрос=одна тема. Если хотите задать ещё вопрос, то начинайте новую тему.
4 Название темы должно составлять сам вопрос, и быть максимально конкретным. Рекомендуется начинать тему словами "Как", "Что", "Почему". А первый пост повторяет вопрос и даёт расширенные сведения.
5 Рекомендуется указывать версию мейкера (2000, 2003, RMXP, RMVX, ACE, IGM, и.т.д.. Это важно, и всё равно ведь спросят.
6 Темы "Пара вопросов", "Помогите", и подобные им - самый лёгкий путь к бану.
7 Поиск находится вверху справа.
А. Названия подразделов этого раздела уточняются. Советы принимаются.

ТЕМА: Вопрос к скриптерам: alias и локальные переменные

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78057

  • Cerberus
  • Cerberus аватар
  • Вне сайта
  • Модератор
  • Собака злая
  • Сообщений: 2269
  • Спасибо получено: 1182
  • Проект месяца 1 местоПрограммист JavaScript 3 место ГотвПисатель 3 местоПроект месяца 3 местоОрганизатор конкурсовПобедитель Сбитой кодировки2 место Сбитая кодировка3 место2 место
Вопрос такой. Имеется некоторая функция, внутри которой создаётся локальная переменная. Есть необходимость эту функцию дополнить, задействовав в дополнении эту локальную переменную. При переопределении через alias эта переменная становится локальной для alias-а, соответственно, код вида:
alias old_foo foo
def foo
  old_foo
  for i in bar
   dosomething(i)
  end
end
где bar - массив, созданный в функции old_foo, т.е. в прежней реализации foo, - такой код уже не работает (переменная bar не существует). Можно ли это как-то обойти, не переопределяя полностью исходную функцию?
Жуть болотная, на лапках, в тапках и с пулемётом...
Администратор запретил публиковать записи гостям.

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78060

  • sinder
  • sinder аватар
  • Вне сайта
  • Мастер
  • Сообщений: 159
  • Спасибо получено: 154
  • Программист JavaScript 3 место Готв2 место ГотвПроект месяца 2 местоРазработчик
Насколько я понял эти alias-ы, то дописанный код в них, добавляется в конец метода, соответственно если пытаться вызвать переменную определенную с помощью alias-a раньше чем она создается, то получим что она не существует. Поэтому думаю, что без переписывания всего метода не обойтись. Хотя может я и не прав.
Последнее редактирование: 9 года 2 мес. назад от sinder.
Администратор запретил публиковать записи гостям.

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78061

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

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78066

  • strelokhalfer
  • strelokhalfer аватар
  • Вне сайта
  • Архитектор Миров
  • Знатный грамотей
  • Сообщений: 1640
  • Спасибо получено: 1078
  • Переводчик2 место 2 место Сбитая кодировкаПрограммист RubyОрганизатор конкурсовДаритель Стимкея
Ты вызываешь оригинал, он отрабатывает и удаляет локальные переменные.
Хотя, попробуй в имени методов добавить *args и &block
"Стрелок, что-то ты неочень похож на свой аватар..."(с)
Администратор запретил публиковать записи гостям.

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78067

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

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78068

  • strelokhalfer
  • strelokhalfer аватар
  • Вне сайта
  • Архитектор Миров
  • Знатный грамотей
  • Сообщений: 1640
  • Спасибо получено: 1078
  • Переводчик2 место 2 место Сбитая кодировкаПрограммист RubyОрганизатор конкурсовДаритель Стимкея
ВРоде эти параметры передают из метода все локальные данные.
def old
   a = "a"
end
alias new old
def old(*args, &block)
   new(*args, &block)
   a = "b"
end

Проверить не могу, пока не дома.
"Стрелок, что-то ты неочень похож на свой аватар..."(с)
Последнее редактирование: 9 года 2 мес. назад от strelokhalfer.
Администратор запретил публиковать записи гостям.

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78069

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

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78075

  • Amphilohiy
  • Amphilohiy аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 547
  • Спасибо получено: 666
  • Оратор2 место ГотвПрограммист RubyПобедитель Сбитой кодировкиУчитель
Все, что произошло на Миле, остается на Миле. Это закон.

Но можно попытаться сделать bar в виде переменной инстанса за счет функций.
def bar
  @bar
end
 
def bar=(arg)
  @bar=arg
end

По необходимости обнулять.
Я верю, что иногда компьютер сбоит, и он выдает неожиданные результаты, но остальные 100% случаев это чья-то криворукость.
Последнее редактирование: 9 года 2 мес. назад от Amphilohiy.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Cerberus, Ren310

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78077

  • Cerberus
  • Cerberus аватар
  • Вне сайта
  • Модератор
  • Собака злая
  • Сообщений: 2269
  • Спасибо получено: 1182
  • Проект месяца 1 местоПрограммист JavaScript 3 место ГотвПисатель 3 местоПроект месяца 3 местоОрганизатор конкурсовПобедитель Сбитой кодировки2 место Сбитая кодировка3 место2 место
Сделал для начала вот так:
class Testing
  def hit
    @hit 
  end
  def hit=(value)
    p value
    @hit=value
  end
  def initialize
    hit = []
    p @hit
  end
end

Testing.new выдаёт nil.

upd: нашёл ошибку. Если в инициализации hit заменить на self.hit, то всё работает как надо. Но это сейчас, к сожалению, не подходит.
Жуть болотная, на лапках, в тапках и с пулемётом...
Последнее редактирование: 9 года 2 мес. назад от Cerberus.
Администратор запретил публиковать записи гостям.

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78078

  • Lekste
  • Lekste аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 911
  • Спасибо получено: 565
  • Программист JavaScript ВетеранПрограммист RubyДаритель СтимкеяОратор
В инициализации hit попробуй с собакой написать, а не как локальную
Администратор запретил публиковать записи гостям.

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78079

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

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78080

  • Amphilohiy
  • Amphilohiy аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 547
  • Спасибо получено: 666
  • Оратор2 место ГотвПрограммист RubyПобедитель Сбитой кодировкиУчитель
Посмотрел, да, не пашет. Этот принцип работает, только если явно обратиться к классу (self.hit=...), но явно такой метод не катит.
Я тут нашаманил, пока думал какие могут быть альтернативы. Прячьте детей и беременных женьщин.
#Наш класс
class Foo
  #Старая функция. Неприступная как шут знает что.
  def bar
    value = 5
  end
 
  #Алиасим и переопределяем
  alias bar1 bar
  def bar
    #Вызываем старую функцию. Трейсер ниже ловит ее и выхватывает биндинг
    bar1
    #В биндинге недавно вызванной функции делаем новое вычисление, а именно спрашиваем локальную переменную
    value = $bind.eval("value")
    #Ваш код
    #...
    #Возврат для проверки
    value
  end
end
 
#Трейсер. Выхватывает вообще все действия в Руби, включая вызов функции
set_trace_func proc { |event, file, lineno, id, binding, klass|
  #События вызова функции. Второе условие важно, вместо Foo впихните свой класс.
  if (event == "call") and (klass <= Foo) then
    #Складируем биндинг для будующего использования. Например в $bind
    $bind = binding
  end
}
 
#Пускаем тест
foo = Foo.new
p foo.bar
Идея в 2 словах - создаем функцию трейсер, которая обрабатывает почти любое действие в Руби. Ставим ленивые "и" условия на наш класс и его производные (можно было бы добавить "and (id == :bar)" для конкретной функции). Там ловим биндинг (читай поле видимости) и складируем в глобальное пространство. Затем производим расчет в биндинге и получаем нужные значения.
Вроде все пашет бодренько, но за падение производительности, лично я, боюсь. Магия темная, в практике раньше не использовал. Ну и в реализации могут быть траблы.
Я верю, что иногда компьютер сбоит, и он выдает неожиданные результаты, но остальные 100% случаев это чья-то криворукость.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Iren_Rin

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78081

  • Lekste
  • Lekste аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 911
  • Спасибо получено: 565
  • Программист JavaScript ВетеранПрограммист RubyДаритель СтимкеяОратор
По-хорошему такого быть вообще не должно. Давай конкретный пример - подумаем как сделать иначе.
Администратор запретил публиковать записи гостям.

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78082

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

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78244

  • Iren_Rin
  • Iren_Rin аватар
  • Вне сайта
  • Мастер
  • Сообщений: 247
  • Спасибо получено: 537
  • УчительПроект месяца 1 местоПроект года 1 местоПрограммист RubyКоммерсант
Я как первый раз прочитал тему пробовал всякое, чтобы получить binding оригинального метода, но до set_tracer_func так и не дошел. И это настоящая темная сторона, спасибо Амфи :)
Представлю свой код, который позволит получить локальные переменные оригинального метода, и при этом не тормозить весь стэк руби. Идея в том, чтобы установить трейсер только на время вызова оригинального метода, а потом обнулить его.
def say
  a = 1
end
 
alias original_say say
def say
  aliased_binding = nil #заводим переменную, чтобы иметь к ней доступ из трейсера
  tracer = proc do |event, file, lineno, id, binding, klass|
    aliased_binding = binding if event == 'return' #записываем в заведенную переменную binding после исполнения оригинальной функции
  end
 
  set_trace_func tracer #устанавливаем трейсер
  original_say
  set_trace_func nil    #обнуляем трейсер, незачем ему вечно тормозить наш код
 
  aliased_binding.eval 'a'
end
 
say
Последнее редактирование: 9 года 2 мес. назад от Cerberus.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Cerberus, Ren310, strelokhalfer, Amphilohiy

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78247

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

Вопрос к скриптерам: alias и локальные переменные 9 года 2 мес. назад #78248

  • Amphilohiy
  • Amphilohiy аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 547
  • Спасибо получено: 666
  • Оратор2 место ГотвПрограммист RubyПобедитель Сбитой кодировкиУчитель
Звучит замечательно! Я не проверял обнуление, но если не ошибаюсь, то на объект можно навесить тонну финализаторов, по одному за вызов функции (в тех экспериментах со слабыми ссылками). Побоялся, что тут может произойти та же история, и руки так не дошли.

Самое веселое, я сейчас даже немного не понимаю как твой код работает :( поэтому тоже пока не проверю.

UPD: Ложная тревога. Проверил, трейсер обнуляется, а я с позором ухожу со светлой еще на месяц :P . А не понял как работает код по той причине, что все описано вне класса, что сбивало меня с толку.
И для совсем любопытных сама проверка
ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ]
Я верю, что иногда компьютер сбоит, и он выдает неожиданные результаты, но остальные 100% случаев это чья-то криворукость.
Последнее редактирование: 9 года 2 мес. назад от Amphilohiy.
Администратор запретил публиковать записи гостям.
Время создания страницы: 0.265 секунд