Thursday, July 15, 2010

Passing arguments to an event

You probbably don't know this but AS3 and JS have a multi-paradigm, imperative and functional. This right now for us means that a function has the same rights as a regular Number. This is something so useful it hurts.

Try this...

function helloWorld(s){
 trace(s);
}
var helloWorld = 0;

You may get this error:

Scene 1, Layer 'Layer 1', Frame 1, Line 5 1151: A conflict exists with definition helloWorld in namespace internal, bitch.

Ok, not the last part. But there is a conflict. Why would there be a conflict? is a function a variable? In AS3, yes. For years the functions have been living under the shadow of variables, but now the functional paradigm considers them as equal! mwahahaha! Make no mistake, this a russian roulette full of bullets pointing the hard work of modular code :)

In AS3 you have events, its listeners functions can only recieve one argument, the event itself. The event is a simple variable that the only true interaction that has with the rest of the scope is the target element. Sometimes we may want to pass some relevant information to the event listener to trigger some cool stuff, there are many alternatives for doing this, you may use class attributes or implement a singleton pattern to create static content readable everywhere.

But let's believe for a second that you just want to pass a single miserable variable to the listener. Many purist will say that you need to extend the Event class and make your own event, just to handle it. Let me tell you... they haven't enter the rabbit hole of functional programming.

If you know nothing of functional programming I reccomend a haskell crash course. Let me show you the solution, then if your head is still over your shoulders or you manage to avoid passing out, because this is gonna be cool (i'm being sarcastic) i'll explain.


function hello(s,e){
 trace("hello... "+s);
}

var  girl = "nurse";

stage.addEventListener(Event.ENTER_FRAME,function(e){hello(girl,e) 
/*do extra stuff involving the arguments or whatever you wanna do*/
});

So, this function basically traces the line "hello... nurse" every time a frame is drawn. I'm even passing the event, so you're basically passing arguments to the event listener.

This saves you the trouble of extending the Event class, creating a new property o telling the client that it can't be done. Some people may argue that this is a lazy and impractical solution, they'd be wrong. There's nothing wrong with this, is not cheating. And some people will try to make you cry, that's a different blog.

A little trouble with inlining functions is that they don't have a name, and I don't mean that in the nameless kinda way from the Jet Li films, this is not cool. Inlining a function like this may be a problem when changing it. Let's fix that...

function hello(s,e){
 trace("hello... "+s);
}

var  girl = "nurse";

var listener;

stage.addEventListener(Event.ENTER_FRAME, listener = function(e){hello(girl,e) 
/*do extra stuff involving the arguments or whatever you wanna do*/
});

There you go, now you have passed arguments to an event listener in a dynamic, simple and clean way. There's some lazy syntax around here, but i'll talk about in a future. there's some reference issues that also will be adressed in future posts.

Now, off you go... go clean up your code, delete all those useless extended event classes, embrace the functional paradigm and go tell the woman you love that you are a true man.

2 comments:

  1. Bitch! Being a Flash/AS3 teacher has made you a f*cking Jedi. Thank for the info, it's been helpful. I don't have any code to refactor so far, but you've given me ideas to solve problems without having to write an extra function and call it inside the listener.

    PS: I don't usually talk/write that way. It's catchy, though. xD

    ReplyDelete
  2. Why stop at anonymous functions? You can also return functions if you like. Pretty useful to compose "criteria" functions for filtering an ArrayCollection using filterFunction.

    ReplyDelete