You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@royale.apache.org by Harbs <ha...@gmail.com> on 2018/12/03 10:53:11 UTC

Gotcha with private access

I just spent a long time tracking down a bug:

I needed to delay execution of a private method called “doPackage()”. Because of “this” weirdness, I used “that” as a reference:
setTimeout(function():*{that.doPackage()},50);

And declared this as that:
var that:* = this;

The problem is that “doPackage” is now a fully qualified so doPackage is not defined.
The solution is to declare the type of that like so:
var that:PackagePanel = this;

I’m not sure if there’s a way to resolve this better.

Harbs


Re: Gotcha with private access

Posted by Alex Harui <ah...@adobe.com.INVALID>.
OK.  If you want to pursue further, examine the actual transpiled code to make sure it build the closures properly.

FWIW, I've never used Promises, but I've never been a fan of function objects and would be tempted to use closures instead of functions.  I think avoiding function objects might future-proof your code as the JS and/or AS scope chain isn't guaranteed to be available on other platforms/runtimes/languages.  IOW, I would have defined a callback method closure like this:

    private function somePromiseHandler():void    {
       appendProgressTextWithString(PanelStrings.PACKAGING + "...");
       setTimeout(doPackage,50);
   }

    private function handlePackage():void{
    	returnSomePromise().then(somePromiseHandler);
    }

This should work, is easier for me to read, and avoids reliance on scope chains.

My 2 cents,
-Alex

On 12/3/18, 1:02 PM, "Harbs" <ha...@gmail.com> wrote:

    Here’s some pseudocode which helps explain better:
    
    
    private function handlePackage():void{
    	var that:PackagePanel = this;
    	returnSomePromise().then(function(result:*):*{
    		appendProgressTextWithString(PanelStrings.PACKAGING + "...");
    		setTimeout(function():*{that.doPackage()},50);
    	});
    }
    
    I need to delay the running of doPackage() to allow for UI to update (without getting into the reason for that necessity). That’s why I’m calling setTimeout().
    
    The function is resolved inside a Promise resolution which messed up this and self. I don’t remember the details offhand. I wrote this code some time ago.
    
    I actually just tried removing “that” and it seemed to work, so I’m not sure what the issue was at the time...
    
    Harbs
    
    > On Dec 3, 2018, at 7:38 PM, Alex Harui <ah...@adobe.com.INVALID> wrote:
    > 
    > I'm not sure I understand.
    > 
    > The compiler is supposed to generate a closure for any parameters of type function.  Is it not doing that?  In ActionScript, you shouldn't need to mess with this/that/self.  I have not looked at any of the code involved, but assuming you are calling something defined like this:
    > 
    > public function setTimeout(fn:Function):void
    > 
    > Then the ActionScript for SWF should work like this:
    > 
    > Public class MyClass
    > {
    >   Public function MyClass()
    >   {
    >       setTimeout(myPrivateFunction);
    >   }
    >   private function myPrivateFunction():void
    >   {
    >   }
    > }
    > 
    > The Transpiler should then generate:
    > 
    > MyClass = function() {
    >    setTimeout(org.apache.royale.utils.Language.closure(MyClass_myPrivateFunction, this, "myPrivateFunction");
    > }
    > 
    > MyClass.prototype.MyClass_myPrivateFunction = function() {};
    > 
    > And it should all work just fine.  If it isn't, start at the beginning and make sure the param for setTImeout is a Function and not an Object or *.  And see if the Transpiler generated the call to Language.closure.
    > 
    > HTH,
    > -Alex
    > 
    > 
    > On 12/3/18, 2:53 AM, "Harbs" <ha...@gmail.com> wrote:
    > 
    >    I just spent a long time tracking down a bug:
    > 
    >    I needed to delay execution of a private method called “doPackage()”. Because of “this” weirdness, I used “that” as a reference:
    >    setTimeout(function():*{that.doPackage()},50);
    > 
    >    And declared this as that:
    >    var that:* = this;
    > 
    >    The problem is that “doPackage” is now a fully qualified so doPackage is not defined.
    >    The solution is to declare the type of that like so:
    >    var that:PackagePanel = this;
    > 
    >    I’m not sure if there’s a way to resolve this better.
    > 
    >    Harbs
    > 
    > 
    > 
    
    


Re: Gotcha with private access

Posted by Harbs <ha...@gmail.com>.
Here’s some pseudocode which helps explain better:


private function handlePackage():void{
	var that:PackagePanel = this;
	returnSomePromise().then(function(result:*):*{
		appendProgressTextWithString(PanelStrings.PACKAGING + "...");
		setTimeout(function():*{that.doPackage()},50);
	});
}

I need to delay the running of doPackage() to allow for UI to update (without getting into the reason for that necessity). That’s why I’m calling setTimeout().

The function is resolved inside a Promise resolution which messed up this and self. I don’t remember the details offhand. I wrote this code some time ago.

I actually just tried removing “that” and it seemed to work, so I’m not sure what the issue was at the time...

Harbs

> On Dec 3, 2018, at 7:38 PM, Alex Harui <ah...@adobe.com.INVALID> wrote:
> 
> I'm not sure I understand.
> 
> The compiler is supposed to generate a closure for any parameters of type function.  Is it not doing that?  In ActionScript, you shouldn't need to mess with this/that/self.  I have not looked at any of the code involved, but assuming you are calling something defined like this:
> 
> public function setTimeout(fn:Function):void
> 
> Then the ActionScript for SWF should work like this:
> 
> Public class MyClass
> {
>   Public function MyClass()
>   {
>       setTimeout(myPrivateFunction);
>   }
>   private function myPrivateFunction():void
>   {
>   }
> }
> 
> The Transpiler should then generate:
> 
> MyClass = function() {
>    setTimeout(org.apache.royale.utils.Language.closure(MyClass_myPrivateFunction, this, "myPrivateFunction");
> }
> 
> MyClass.prototype.MyClass_myPrivateFunction = function() {};
> 
> And it should all work just fine.  If it isn't, start at the beginning and make sure the param for setTImeout is a Function and not an Object or *.  And see if the Transpiler generated the call to Language.closure.
> 
> HTH,
> -Alex
> 
> 
> On 12/3/18, 2:53 AM, "Harbs" <ha...@gmail.com> wrote:
> 
>    I just spent a long time tracking down a bug:
> 
>    I needed to delay execution of a private method called “doPackage()”. Because of “this” weirdness, I used “that” as a reference:
>    setTimeout(function():*{that.doPackage()},50);
> 
>    And declared this as that:
>    var that:* = this;
> 
>    The problem is that “doPackage” is now a fully qualified so doPackage is not defined.
>    The solution is to declare the type of that like so:
>    var that:PackagePanel = this;
> 
>    I’m not sure if there’s a way to resolve this better.
> 
>    Harbs
> 
> 
> 


Re: Gotcha with private access

Posted by Alex Harui <ah...@adobe.com.INVALID>.
I'm not sure I understand.

The compiler is supposed to generate a closure for any parameters of type function.  Is it not doing that?  In ActionScript, you shouldn't need to mess with this/that/self.  I have not looked at any of the code involved, but assuming you are calling something defined like this:

public function setTimeout(fn:Function):void

Then the ActionScript for SWF should work like this:

Public class MyClass
{
   Public function MyClass()
   {
       setTimeout(myPrivateFunction);
   }
   private function myPrivateFunction():void
   {
   }
}

The Transpiler should then generate:

MyClass = function() {
    setTimeout(org.apache.royale.utils.Language.closure(MyClass_myPrivateFunction, this, "myPrivateFunction");
}

MyClass.prototype.MyClass_myPrivateFunction = function() {};

And it should all work just fine.  If it isn't, start at the beginning and make sure the param for setTImeout is a Function and not an Object or *.  And see if the Transpiler generated the call to Language.closure.

HTH,
-Alex


On 12/3/18, 2:53 AM, "Harbs" <ha...@gmail.com> wrote:

    I just spent a long time tracking down a bug:
    
    I needed to delay execution of a private method called “doPackage()”. Because of “this” weirdness, I used “that” as a reference:
    setTimeout(function():*{that.doPackage()},50);
    
    And declared this as that:
    var that:* = this;
    
    The problem is that “doPackage” is now a fully qualified so doPackage is not defined.
    The solution is to declare the type of that like so:
    var that:PackagePanel = this;
    
    I’m not sure if there’s a way to resolve this better.
    
    Harbs