473,395 Members | 1,368 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

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

tai
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.

Nov 17 '06 #1
9 3496

tai wrote:
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.
I can't really tell what you want to do from this post. It looks like
you're trying to program JS using some other language's syntax.

Is this this sort of thing you had in mind?

function bar_plugin_func() {
setTimeout(function() {
// logic goes here
}, 1000);
}

Google function closures. You'll find

http://www.jibbering.com/faq/faq_notes/closures.html

written by our very own Richard Cornford.

Perhaps though all you want is a local function. In JS, a function has
scrope, can be assigned, and is generally treated just like any other
variable.

Perhaps some more clarification would be in order?

Nov 17 '06 #2
tai
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.
Nov 18 '06 #3
VK
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.

Nov 18 '06 #4

tai wrote:
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?
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.

For starters, "goto" is a reserved keyword, so you'll need a different
name for your function there.
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]);

Nov 18 '06 #5
tai
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.
Nov 19 '06 #6
tai
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]);
Nov 19 '06 #7

tai wrote:
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.
Sure. Then send add your functions to the constructor and add internal
wrappers instead of explicit external wrappers:

function FSM() {
this.funcs = arguments;
}

FSM.prototype.callFunc = function(num) {
switch (this.funcs[num]) {
case 0: return this.callFunc(3);
case 1: return this.callFunc(2);
// or whatever
default: return;
}
}

my question is: how are you going to determine the proper (Markovian)
sequence of functions, without some return value from the functions?
Will it be hardcoded? Or will it be passed in as an argument?
>
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);
The proper way to handle async stuff is just to put a callback at the
end of your onload/onreadystatechange handler, and "break out" of the
state machine in your calling function. It really doesn't change the
logic in any way with this problem.
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.
I would still like to know more about this problem:

- what do these functions do (in general)?
- is their return value used for anything?
- are they generally going to need arguments, and if so, where will
they get them from within your FSM?
- how are they going to know about each other & which one to call next?

So you will need an API after all, and you're going to need to define
some parameters here, otherwise we can't help you. It seems your
problem here is not with the JavaScript language, but with clearly and
sufficiently defining the domain and parameters of your particular
problem. But it sounds interesting and I would like to know where
you're going with this and what problem it is you've decided to tackle
this way (unless you're just doing it for fun).

Nov 19 '06 #8
VK

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.

Nov 19 '06 #9
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.
Nov 19 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Jonathan | last post by:
I'm puzzled by Python's behavior when binding local variables which are introduced within exec() or execfile() statements. First, consider this simple Python program: # main.py def f() : x = 1...
2
by: Kench | last post by:
I was curious and playing with pointers and references to see what's different between them. Other than the obvious ones involving C++ syntax & things like references cannot be modified with...
18
by: Joe | last post by:
Hi, I am trying to alter the refresh rate of an online webpage in a webbrowser control using MFC. However the Timer ID is stored in a local variable and I don't know how to access it. Is there a...
5
by: john | last post by:
By doing: void MyClass::MyFunction() { static int myvar; .... } We can defined a function local variable 'myvar' that keeps its value from call to call (the point is that the variable can...
7
by: Edward Yang | last post by:
A few days ago I started a thread "I think C# is forcing us to write more (redundant) code" and got many replies (more than what I had expected). But after reading all the replies I think my...
4
by: octavio | last post by:
Hello members of the comp.lang.c newsgroup. Please I need you help on the following one. Compiling the simple code I'm getting this error message. Why ? Please what's the correct type of the fb...
2
by: Jess | last post by:
Hello, I understand that if a function "f" has a local variable "a", and after it returns, "a" vanishes. If "f" returns "a" as a result, then I noticed the following: 1. if the return type is...
7
by: pauldepstein | last post by:
#include <iostream> using namespace std; double & GetWeeklyHours() { double h = 46.50; double &hours = h; return hours; }...
2
by: tolgs | last post by:
I have a variable with a numberic value calculated/defined within a function. In some other part of the page, I want to be able to use the value of that variable; however, since that variable is...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.