Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   hurlant eval, чудеса с областью видимости в as3 (http://www.flasher.ru/forum/showthread.php?t=168618)

maksimov 22.09.2011 17:54

hurlant eval, чудеса с областью видимости в as3
 
Код AS3:

package com
{
        public class Util
        {
                public static function print(arg:String):void
                {
                        trace(arg);
                }
        }
}



далее начинаются чудесаааатые чудеса:

Код AS3:

import com.Util;
...
Util.print('test1');
 
var src:String =
"namespace COM = 'com';\n" +
"use namespace COM;\n" +
"Util.print('test2');";
 
ByteLoader.loadBytes(esc.eval(src));

Получаю в трейсе:
Цитата:

test1
test2

Код AS3:

import com.Util;
...
//Util.print('test1');
 
var src:String =
"namespace COM = 'com';\n" +
"use namespace COM;\n" +
"Util.print('test2');";
 
ByteLoader.loadBytes(esc.eval(src));

Получаю:
Цитата:

ReferenceError: Error #1065: Переменная Util не определена.
То есть, если я не использовал эту функцию ранее - она оказывается невидна.

silin 22.09.2011 18:14

да вобщем нет тут ничего чудесного: если на функцию\класс нет ссылок в коде, то логично, что их нет и во флешке, не ?

Aquahawk 22.09.2011 18:17

Никаких чудес, в евале можно использовать только те классы, что вы использовали просто так, иначе их упоминаний не будет в заголовках swf файла( точнее abc файла) и они не могут быть использованы в динамике. Попробуйте получить имя этого класса через getDefinitionByName и у вас тоже ничего не получится. Для того чтоб класс можно было использовать достаточно его просто упомянуть, например так:
Код AS3:

Util;

Это происходит потому что esc не собирает новую флешку с новыми хедерами, а исполняет код сам, тамарином.

Добавлено через 30 секунд
блин, silin опередил

wvxvw 22.09.2011 18:17

Нет, это не область видимости, это класс Util не скомпилировался (т.как незачем) второй раз. Если класс не использовать, то компилятор его не прилинкует. А eval() скорее всего не занимается поиском (да и негде ему...) существующих классов, он просто скомпилировал код типа getproperty symboltableoffset XX ("Util") ну а когда оно выполнилось, оказалось, что строка из таблицы символов не относится ни к какому из известных объектов.

maksimov 22.09.2011 19:27

silin, Aquahawk, wvxvw - большое спасибо! =)



Злоупотреблю вашей добротой к моей глупости и моему невежеству, и спрошу ещё вот какую вещь:

У меня есть ArrayCollection из объектов, свойства которых я использую в коде, который я потом eval'ю, следующим образом:

Код AS3:

var code:String = "";
for (var i:int = 0; i < attributes.length; i++)
{
        if (attributes[i].type == "String")
        {
                code += "var " + a[i].id + ":String = \"" + a[i].value + "\";\n";
        }
        else
        {
                code += "var " + a[i].id + ":int = " + a[i].value + ";\n";
        }
}
code += mycode; // добавление кода, который в ходе своей работы изменяет значения переменных, добавленных в код выше

Как лучше, загонять значения этих переменных в конце кода?

silin 22.09.2011 19:54

непонятно тебя
трудно угадать будет ли кому-то лучше, если загонять в конце :)

maksimov 22.09.2011 20:23

Цитата:

Сообщение от silin (Сообщение 1033820)
непонятно тебя

Попробую перефразировать.

В строковой переменной code я формирую текст кода, который потом выполняю с помощью esc.eval(code).

У меня есть некий ArrayCollection, каждый элемент которого является объектом с вот такой структурой: {type: "Int", id: "zozo", value: 25}

Я добавляю объекты из этого ArrayCollection, в формируемый мной текст кода, в виде инициализации переменных:

Код AS3:

for (var i:int = 0; i < myAC.length; i++)
{
        if (myAC[i].type == "String")
        {
                code += "var " + myAC[i].id + ":String = \"" + myAC[i].value + "\";\n";
        }
        else
        {
                code += "var " + myAC[i].id + ":int = " + myAC[i].value + ";\n";
        }
}
 
// в результате, {type: "Int", id: "zozo", value: 25} попадает в код в виде var zozo:int = 25;


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


Цитата:

Сообщение от silin (Сообщение 1033820)
трудно угадать будет ли кому-то лучше, если загонять в конце :)

=))

Добавлено через 20 минут
Кажись нашол.

Решением является такой код:
Код AS3:

for (i = 0; i < myAC.length; i++)
{
        code += "Util.set(" + i + ", " + myAC[i].id + ");\n"
}
 
...
 
 
public static function set(arg1:int, arg2:*):void
{
        myAC[arg1].value = arg2;
}


dimarik 22.09.2011 22:06

Нашел? Ай, молодец.


Часовой пояс GMT +4, время: 20:00.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.