Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Injecting local variable to a function - Can it be done?

Reply
Thread Tools

Injecting local variable to a function - Can it be done?

 
 
tai
Guest
Posts: n/a
 
      11-17-2006
Hi.

I'm looking for a way to define a function that's only effective inside
specified function.

Featurewise, here's what I want to do:

bar_plugin_func = function() { ...; setTimeout(...); ... };
wrap_func(bar_plugin_func);
bar_plugin_func(); // calls custom "setTimeout"

So while plugin developer thinks s/he's calling top-level function,
I want to hook it by somehow injecting local variable with the same
name.

Simply doing something like

;(function() { setTimeout = function() { ...my custom implementation
})();

is not ideal, as that'll taint global scope. Actually, I can live with
that for now,
but it's my technical interest to find a way to define it locally.

>From the quote in following reference, it says:


- http://www.unix.org.ua/orelly/web/jscript/ch11_05.html
> Variable Scope
> We saw above that top-level variables are implemented as properties of the current window
> or frame object. In Chapter 6, Functions, we saw that local variables in a function are
> implemented as transient properties of the function object itself.


So how can I manipulate "transient properties of the function object
itself"?

Thanks in advance.

 
Reply With Quote
 
 
 
 
tai
Guest
Posts: n/a
 
      11-18-2006
> Perhaps some more clarification would be in order?

OK...let me try again.

I'm currently developing a JS-based framework that handles
user-registered functions. Just before executing these registered
functions, the framework redefines, or newly defines several
"top-level" methods to coordinate interaction between each
registered functions. So it's not limited to "setTimeout" method only.

Here's somewhat different, but more concrete example.
One of my framework components is FSM (finite state machine)
class, and it can be used in following manner:

var func0 = function func0(arg) { alert("func0"); goto(func2);
alert("notreached") };
var func1 = function func1(arg) { alert("func1"); goto(-1) };
var func2 = function func2(arg) { alert("func2"); goto(-1, true) };

var sm = new StateMachine(func0, func1, func2);
sm.start(func0, arg); // alerts in order of: func0, func2, func1

In above example, the framework defines "goto" method, which
cause a immediate transition to specified state. And this is
where my initial question comes in.

To provide "goto" or any other external functions, I currently
add them to global scope. However, I feel that's an overkill -
these just need to be effective in registered functions. I want
to use them as if they are "top-level", but I also want global
namespace kept clean.

I know JS's scoping rule will make any attempt void once these
registered functions do a nested function call (which resets
scope chain). However, how about directly inside these registered
functions? Is it possible to re-define top-level functions just
directly inside these (= func0, func1, func2) registered methods?

> > Featurewise, here's what I want to do:
> >
> > bar_plugin_func = function() { ...; setTimeout(...); ... };
> > wrap_func(bar_plugin_func);
> > bar_plugin_func(); // calls custom "setTimeout"
> >
> > So while plugin developer thinks s/he's calling top-level function,
> > I want to hook it by somehow injecting local variable with the same
> > name.
> >
> > Simply doing something like
> >
> > ;(function() { setTimeout = function() { ...my custom implementation
> > })();
> >
> > is not ideal, as that'll taint global scope. Actually, I can live with
> > that for now, but it's my technical interest to find a way to define it locally.


 
Reply With Quote
 
 
 
 
VK
Guest
Posts: n/a
 
      11-18-2006
> I know JS's scoping rule will make any attempt void once these
> registered functions do a nested function call (which resets
> scope chain). However, how about directly inside these registered
> functions? Is it possible to re-define top-level functions just
> directly inside these (= func0, func1, func2) registered methods?


Other words, is it possible to re-compile run-time the execution
context? Actually JavaScript is one of few programming languages (if
not the single one at all) that allows you to do such things, but for
that you have of course to abandon the idea of working with the
compiled code itself and use new Function(strSource) instead.

By carefully tweaking and a bit memory leaking you can emulate
Perl-like local scope for a set of function (var visible in this
function and all functions called from within this function). But
AFAICT it doesn't help in your situation because you want the effect
for *any* random function sent to the constructor.

 
Reply With Quote
 
tai
Guest
Posts: n/a
 
      11-19-2006
Hmm...maybe some clever use of "eval" might solve this problem.
Say there's a method like

var replacements = { needtrap: function() { ... } };
var func0 = function() { needtrap() };

What I want to do is something like

with (replacements) { // install intercepting scope
func0();
}

Of course this won't work because scope chain gets reset when calling
func0 method. But with eval, maybe I can redefine it dynamically to

var func0 = function() { with (replacements) { func0 } };

But evaling function definition has a issue of "free"ing a binding to a
local scope at the time of initial definition. So I guess the real
solution
is to redefine it as

var func0 = function() {
with (original_func0_scope) { // preserve original scope at the
time of initial definition
with (replacements) { // install intercepting scope
// "needtrap" will be intercepted, bu others will work as
originally defined
func0;
}
}
};

which I'm not sure if it's possible or not.

Maybe I need to require registering functions to provide an API to
return such information (original_func0_scope = func0.get_scope()) ,
or just go with global override.

> > I know JS's scoping rule will make any attempt void once these
> > registered functions do a nested function call (which resets
> > scope chain). However, how about directly inside these registered
> > functions? Is it possible to re-define top-level functions just
> > directly inside these (= func0, func1, func2) registered methods?

>
> Other words, is it possible to re-compile run-time the execution
> context? Actually JavaScript is one of few programming languages (if
> not the single one at all) that allows you to do such things, but for
> that you have of course to abandon the idea of working with the
> compiled code itself and use new Function(strSource) instead.
>
> By carefully tweaking and a bit memory leaking you can emulate
> Perl-like local scope for a set of function (var visible in this
> function and all functions called from within this function). But
> AFAICT it doesn't help in your situation because you want the effect
> for *any* random function sent to the constructor.


 
Reply With Quote
 
tai
Guest
Posts: n/a
 
      11-19-2006
> For starters, "goto" is a reserved keyword, so you'll need a different
> name for your function there.


Thanks, I simply thought "goto" was OK as JS does not have "goto" and
IE JScript accepted it - I'll change that.

> Hm, this is a distinctly non-JavaScript way of going about things,
> which leads me to think that you're experience in a different language
> (Java, perhaps?) and are trying out techniques that may be appropriate
> in a different language but are quite non-idiomatic to JavaScript.


Close, but not really. For FSM, I first started with something similar
to your example, but following two goals drove me to this state:

1. I wanted the use of this framework straightforward and transparent
2. Asynchronous operation support (like XmlHttpRequest)

For goal #1, I wanted to keep registering function look clean as
possible so they would not depend too much on this framework.
This helps porting/reusing existing functions.

And due to goal #2, I had to abandon use of "return <next>;" way
to initiate state shift - thus introduction of "goto". This is somewhat
off-topic, but things start to look interesting when you think about
integrating async op like below into FSM:

var func0 = function() {
var img = new Image(); img.src = "..."; img.onload = function() {
.... }; ...;
}
...
var sm = new StateMachine(func0, func1, ...);
sm.start(func0, arg);

But I must agree this is "quite non-idiomatic to JavaScript" like
you said, as this implementation was really tricky. OTOH, I think
I'm getting close to establishing goal #1.

> > var func0 = function func0(arg) { alert("func0"); goto(func2);
> > alert("notreached") };
> > var func1 = function func1(arg) { alert("func1"); goto(-1) };
> > var func2 = function func2(arg) { alert("func2"); goto(-1, true) };
> >
> > var sm = new StateMachine(func0, func1, func2);
> > sm.start(func0, arg); // alerts in order of: func0, func2, func1

>
>
> I would do this (if I understand you correctly) like so:
>
> function StateMachine() {
> // assumes all arguments are callable as functions -
> // in real life you'll want to verify this
> this.funcs = arguments;
> }
>
>
> StateMachine.prototype.callFunc = function(args) {
> var num = -1;
> if (args.length && args.length >= 1) {
> num = args[0];
> args = args[1];
> }
> if (num >= 0) {
> this.callFunc(this.funcs[num](args));
> }
> }
>
> // You can either pass in the functions as anonymous like so,
> // or first define some functions and pass them in by name
> var sm = new StateMachine(function() {
> alert(1);
> // return value determines next function to be called
> // you can also have some logic here to decide what
> // that should be
> return [2];
> },
> function(arg) {
> alert(arg);
> return [-1];
> },
> function() {
> alert(3);
> return [1, 'howdy!'];
> });
>
> // then you call the number you want to start with as first item in an
> array
> // if you want multiple args you can pass those as a nested array
> // remember in JS you can mix types in a single array
> sm.callFunc([0]);


 
Reply With Quote
 
VK
Guest
Posts: n/a
 
      11-19-2006

tai wrote:
> Hmm...maybe some clever use of "eval" might solve this problem.
> Say there's a method like
>
> var replacements = { needtrap: function() { ... } };
> var func0 = function() { needtrap() };
>
> What I want to do is something like
>
> with (replacements) { // install intercepting scope
> func0();
> }
>
> Of course this won't work because scope chain gets reset when calling
> func0 method. But with eval, maybe I can redefine it dynamically to
>
> var func0 = function() { with (replacements) { func0 } };


I am still not sure if I got right the architecture you are willing to
achieve, so sorry if a useless advise below.

Unless you need to run your code in JScript.NET compiled with /quick -
unless that you can always augment the function object:

<script type="text/javascript">
function CallDispatcher() {
for (var i=0; i<arguments.length; ++i) {
if (typeof arguments[i] == 'function') {
arguments[i]['$goto'] = new Function('window.alert('+i+');');
arguments[i]();
}
}
}

function f1() {
if (f1.$goto) {
f1.$goto();
}
}

function f2() {
if (f2.$goto) {
f2.$goto();
}
}

function f3() {
if (f3.$goto) {
f3.$goto();
}
}


function init(arg) {
CallDispatcher(f2,f3,f1);
}

window.onload = init;
</script>

>From the other side (as other poster pointed out) it looks like you are

brute force trying to emplement a structure of one language into all
another language. Usually it doesn't work or it leads to ugly and
unstable solutions. Maybe instead of code samples it would be more
helpful to see the block-schema you want to implement: so some standard
OOP solution could be suggested.

 
Reply With Quote
 
Bart Lateur
Guest
Posts: n/a
 
      11-19-2006
tai wrote:

>Simply doing something like
>
> ;(function() { setTimeout = function() { ...my custom implementation
>})();
>
>is not ideal, as that'll taint global scope. Actually, I can live with
>that for now,
>but it's my technical interest to find a way to define it locally.


make setTimeout a (local) var?

var setTimeout = function () { .... };

--
Bart.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Injecting a global into a defined function?? Cong Ma Python 0 01-15-2009 06:28 PM
Can we make a local variable in a function as global variable??? sairam Python 2 04-05-2007 07:16 PM
Injecting a variable attribute from a select grid control Thaddius39 ASP .Net 0 11-20-2005 04:27 AM
Injecting code into a function George Sakkis Python 17 04-26-2005 05:35 PM
Injecting a C side object into the local dict Jamie R. Parent Python 1 02-11-2005 07:31 PM



Advertisments