1. ActionScript / Говнокод #2386

    −190.8

    1. 1
    2. 2
    3. 3
    4. 4
    if (flash.net.getClassByAlias("foo.bar.VO") == null){
              flash.net.registerClassAlias("foo.bar.VO", foo.bar.VO);}
          } catch (e:Error) {
              flash.net.registerClassAlias("foo.bar.VO", foo.bar.VO); }

    Так во флексовом фреймворке регистрируются алиасы для RPC классов... Нелогичность ситуации не сразу очевидна, поэтому опишу:
    При загрузке модулей может возникнуть ситуация, когда алиас уже зарегистрирован для другого класса, поэтому нужно проверить, а не был ли алиас зарегистрирован раньше. Иначе, его нужно зарегистрировать. Исторически, этой проверки сначала не было, данный код - это фикс вышеописаной проблемы. Пытаясь разобраться, что же все-таки случилось - скорее всего "писатель" не подозревал, что getClassByAlias() не может вернуть null - а выяснил он это, когда код вывалился с ошибкой, вот он не долго думая завернул это все в try-catch...
    Из мелких деталей: в рамках AS3 сравнение сложных типов с null - бессмысленная, и более того вредная операция, т.как выражение в условии всегда кастуется к Boolean, и компилятор не умеет делать оптимизации для таких случаев.

    Запостил: wvxvw, 08 Января 2010

    Комментарии (5) RSS

    • Без try не взлетит?
      Ответить
    • try {
      if (flash.net.getClassByAlias("foo.bar.VO") == null){
                flash.net.registerClassAlias("foo.bar.VO", foo.bar.VO);}
            } catch (e:Error) {
                flash.net.registerClassAlias("foo.bar.VO", foo.bar.VO); }


      Сорри, try отвалился когда постил.
      А вообще, по логике должно было быть так:

      try 
      {
          flash.net.getClassByAlias("foo.bar.VO");
      }
      catch (error:Error)
      {
          flash.net.registerClassAlias("foo.bar.VO", foo.bar.VO);
      }
      Ответить
    • "Из мелких деталей: в рамках AS3 сравнение сложных типов с null - бессмысленная, и более того вредная операция, т.как выражение в условии всегда кастуется к Boolean, и компилятор не умеет делать оптимизации для таких случаев. "

      http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/statements.html#if - ясно даёт понять, что ожидаемый тип выражения в скобках - Boolean.

      http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/net/package.html#getClassByAlias%28%29 - ясно даёт понять, что возвращаемое функцией значение - ссылка на объект класса Class (ссылка может быть равна null).

      Эээ, Boolean это Class? Объясните пожалуйста вредность и бессмысленность логичного подставления выражения типа Boolean в место, где ждут в нетерпением именно Boolean?
      Ответить
    • 1. Эта функция никогда не возвращает null потому, что в случае, если класс не зарегистрирован она бросит ошибку (но ничего не вернет). Выбрасывание ошибки можно представить как своего рода альтернатвную реализацию возврата из функции, со спорным преимуществом - можно вернуться на несколько стак фреймов (вместо одного), а так же можно "вернуть" неожиданный тип данных. Почему-то стиль программирования с выбрасыванием ошибок ассоциируется с Java :) очень любят они это дело...
      2. Boolean - это класс, так он представлен в виртуальной машине, но к предмету обсуждения это отношения не имеет, т.как Class при касте к Boolean всегда вернет true, т.е. Boolean(Boolean) == true, при чем всегда :) Кроме того, сериализовать его таким образом не за чем, но, даже если вы зачем-то попытаетесь добавить алиас на него, то ни на что это не повлияет т.как значения типа Boolean записываются по другим правилам, и алиас там не учитывается.
      3. Вам такое представление кажется логичным, а мне бессмысленным, потому что уже наличие if() для меня однозначно указывает на то, что выражение надо привести к Boolean. Если вам нравится много писать ради получения идентичного результата, который можно получить меньшими усилиями - это, как тут принято говорить, "китайский" подход :) Т.е. бессмысленное нагромождение лишних сущностей.
      В варианте типа if (foo == null) будет больше операций, но они совсем не ресурсоемкие, так что если вы не гоняетесь за миллисекундами, то пишите, как хотите, погоды это не сделат, просто не удобно.
      Ответить
    • C:\flex\trunk\bin>swfdump -abc C:\projects\tests\trunk\bin\index.swf
      function tests:TestRandom::private:test()::void
          maxStack:2 localCount:2 initScopeDepth:9 maxScopeDepth:10
              debugfile       "C:\projects\e4xu\trunk\src;tests;TestRandom.as"
              debugline       19
              getlocal0
              pushscope
              debug           1 6 0 21
              debugline       21
              newobject       {0}
              coerce          :Object
              setlocal1
              debugline       22 
      		
      		/*------ case 0 start -----*/
      		
              getlocal1 // put the value of a local variable on stack
              convert_b // convert it to Boolean
              iffalse         L0 // if value is not 0, proceed to label L0
      
              findpropstrict  :trace
              pushstring      "case 0"
              callproperty    :trace (1)
              pop
      		
      		/*------ case 0 end (total instructions: 3) -----*/
      		
          L0: debugline       23
      	
      		/*------ case 1 start -----*/
      		
              getlocal1 // put the value of a local variable on stack
              pushnull // put the value of null on stack
              ifeq            L1 // compare values 
      						// (here you must compare at least several bytes, not a single bit!)
      						// if values are equal, then proceed to label L1
      
              findpropstrict  :trace
              pushstring      "case 1"
              callproperty    :trace (1)
              pop
      		
      		/*------ case 1 end (total instructions: 3) -----*/
      		
          L1: debugline       24
              returnvoid
          0 Extras
          0 Traits Entries
      Ответить

    Добавить комментарий