Join 3,418 readers in helping fund MetaFilter (Hide)


Flash AS3 - Inaccessible Method
January 9, 2013 8:49 AM   Subscribe

Why is this method inaccessible? My document class (Main) has a public function setButtonStates(). I have a custom class that extends MovieClip that needs to access that function. There are 5 instances of this class on the stage at compile-time (and they are never removed) but the compiler isn't happy. It says "1195 Attempted access of inaccessible method setButtonStates through a reference with static type Main".

Basically, what I'm working on is an undo button. I have 3 classes that perform "undoable" actions. When they push an operation to the undo stack the undo/redo buttons need to be refreshed to reflect that there is now something to undo/redo. Unfortunately none of the 3 classes seem to be able to access the function. They are able to run the code in the function but I'd rather not have to copy the code 3 times.

I've been through 2 pages of google results and every time the solution was that the function was private (mine was originally but I changed it to public) or the function was a getter/setter.

(also, bonus points if you tell me why root["property"] is ok and Main(root).property is ok but root.property causes a compile error and also why root["property"] doesn't work when root["instance_of_item_on_stage"].parent["property"] works. )
posted by missmagenta to Computers & Internet (12 answers total)
 
First question I'm not clear, but for the bonus question, "property" is a property of the Main class, not the MainTimeline class, which is what root is. So if you just access root without typing it to the Main class, then the compiler doesn't know for sure that property exists. root["property"] is handled differently by the compiler than root.property and will execute slightly slower because it is doing error checking at run-time rather than at compile-time.


How are you trying to access setButtonStates() ? Are you trying to access it through Main.setButtonStates() instead of through an instance of the Main class? Because that would give you that error.
posted by RobotHero at 9:31 AM on January 9, 2013


I've tried various ways but currently using:

Main(root).setButtonStates();
posted by missmagenta at 10:45 AM on January 9, 2013


I would expect an "undefined" error instead of "inaccessible method," but are you certain root is not undefined? trace(root) if you're not sure.

And how is the function declared?

Something like:

public class Main {

public function setButtonStates() {

}

}

posted by RobotHero at 11:17 AM on January 9, 2013


trace(root) gives [object Main]


public class Main extends MovieClip {
//some vars here
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
public function setButtonStates():void {
undoButton.enabled = undoManager.canUndo();
redoButton.enabled = undoManager.canRedo();
}
}


I'm able to access properties of root in the same function. Main(root).undoManager.pushUndo(op); compiles (and works) just fine.

If I change the function call to something that doesn't exist the error changes to "undefined" rather than inaccessible, so it seems it does acknowledge that the method exists.
posted by missmagenta at 12:03 PM on January 9, 2013


Is it something weird like it's not using the new definition of Main? (Thus still treating setButtonStates as private) Throw a line of gibberish in the Main class, see if it throws an error.
posted by RobotHero at 12:35 PM on January 9, 2013


Can other methods of Main be called from the same location?

What if you created a new method for Main called setButtonStates2 that does nothing?
Could you call that method without this error?
What if you copy the contents of setButtonStates into setButtonStates2?
What if you delete setButtonStates and then change the name of setButtonStates2 to setButtonStates?
At what point does the problem crop up again? Or does that somehow work?
posted by RobotHero at 12:43 PM on January 9, 2013


Other changes to main are appearing (new functions are recognised, gibberish throws an error)

Creating a new public method in main and trying to call that instead throws the same error. Ditto renaming it, removing the function and creating a new function that does nothing.

I've even tried restarting flash. (my first thought was that it was somehow using the old main.as)

(thanks for the help btw, I know we're not really getting anywhere but the effort is appreciated and it makes me feel better than I'm not the only one totally stumped by it!)
posted by missmagenta at 12:55 PM on January 9, 2013


We're not getting nowhere, we're eliminating things that it's not. :)


So it's a problem with all methods of Main, not just the one method. Or at least it's a problem with calling methods of Main the way you are from where you are.

Maybe there's a clue in how the function and class you're calling this FROM is defined?



And if you need to resort to an alternate approach, my own OO habit for this sort of thing is I'd use a bubbling event which Main is listening for, like so:


in Main constructor ...

addEventListener(BUTTON_STATES,setButtonStates);

In the child ...

dispatchEvent(new Event(Main.BUTTON_STATES,true));

posted by RobotHero at 1:23 PM on January 9, 2013


That gives me Access of undefined property BUTTON_STATES in Main
posted by missmagenta at 1:35 PM on January 9, 2013


Oh, sorry, you'd have to define BUTTON_STATES in Main:

public static const BUTTON_STATES:String="BUTTON STATES EVENT";
posted by RobotHero at 1:41 PM on January 9, 2013


It works! Doesn't explain why I can't access methods in the regular way (or why I appear to be the only person in world who cant heh), especially when I can access properties but at this point, I don't even care anymore. It compiles and it works. If I have this problem again I can work around it in the same way. Thanks for all your help.
posted by missmagenta at 1:51 PM on January 9, 2013


The type of root is DisplayObject. DisplayObject is dynamic, which means you can set and retrieve properties on it using the [] operator, but if you try to retrieve a property using the dot operator you will get that error, because DisplayObject doesn't have a declared property with the name. The compiler doesn't know at compile time that the run time type of root is Main, so it can't assume that your property will be available and throws a compile error. When you cast the root property to Main, you tell the compiler that you know better than it does, and to suppress the error.
posted by klanawa at 2:35 PM on January 9, 2013


« Older Sometimes, I am a front-end we...   |  I've just signed up for a virt... Newer »
This thread is closed to new comments.