[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.javascript

Bind custom function to the all Function objects

Cezary Tomczyk

6/13/2014 2:33:00 PM

I am looking for a solution where I can bind custom function to the all
Function objects. Whenever any function/method will be called I'd like
to call my custom function. I am going to use it only for
testing/debugging. Doesn't have to be cross-browser.

Can someone suggest from where to start?

--
Cezary Tomczyk
http://www.ct...
12 Answers

Thomas 'PointedEars' Lahn

6/13/2014 2:57:00 PM

0

Cezary Tomczyk wrote:

> I am looking for a solution where I can bind custom function to the all
> Function objects. Whenever any function/method will be called I'd like
> to call my custom function. I am going to use it only for
> testing/debugging. Doesn't have to be cross-browser.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
What does this mean?

> Can someone suggest from where to start?

No, because it is not possible.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Cezary Tomczyk

6/13/2014 3:21:00 PM

0

2014-06-13 16:56, Thomas 'PointedEars' Lahn wrote:
> Cezary Tomczyk wrote:
>
>> I am looking for a solution where I can bind custom function to the all
>> Function objects. Whenever any function/method will be called I'd like
>> to call my custom function. I am going to use it only for
>> testing/debugging. Doesn't have to be cross-browser.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> What does this mean?

This means that if one browser support required functionality then I'll
use that specified browser in my case.

>> Can someone suggest from where to start?
>
> No, because it is not possible.

What a pity.

--
Cezary Tomczyk
http://www.ct...

Michael Haufe (\"TNO\")

6/13/2014 3:40:00 PM

0

"On Friday, June 13, 2014 9:32:37 AM UTC-5, Cezary Tomczyk wrote:
> I am looking for a solution where I can bind custom function to the all
> Function objects. Whenever any function/method will be called I'd like
> to call my custom function. I am going to use it only for
> testing/debugging. Doesn't have to be cross-browser.
>
> Can someone suggest from where to start?

Potentially with Proxies, but you'll have to do a bit of manual work:

---

function foo(){
alert("Foo")
}

var bar = Proxy(foo,{
apply: function(target,thisArg,args){
alert("Proxy was called");
target.apply(thisArg,args);
}
})

bar()

---

more: <http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies...

Thomas 'PointedEars' Lahn

6/13/2014 5:02:00 PM

0

Cezary Tomczyk wrote:

> 2014-06-13 16:56, Thomas 'PointedEars' Lahn wrote:
>> Cezary Tomczyk wrote:
>>> I am looking for a solution where I can bind custom function to the all
>>> Function objects. Whenever any function/method will be called I'd like
>>> to call my custom function. I am going to use it only for
>>> testing/debugging. Doesn't have to be cross-browser.
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> What does this mean?
>
> This means that if one browser support required functionality then I'll
> use that specified browser in my case.

Learn to think in terms of versions of implementations, not browsers.

>>> Can someone suggest from where to start?
>> No, because it is not possible.
>
> What a pity.

<http://www.catb.org/~esr/faqs/smart-questions.htm...

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Cezary Tomczyk

6/13/2014 8:42:00 PM

0

2014-06-13 19:01, Thomas 'PointedEars' Lahn wrote:
> Cezary Tomczyk wrote:
>
>> 2014-06-13 16:56, Thomas 'PointedEars' Lahn wrote:
>>> Cezary Tomczyk wrote:
>>>> I am looking for a solution where I can bind custom function to the all
>>>> Function objects. Whenever any function/method will be called I'd like
>>>> to call my custom function. I am going to use it only for
>>>> testing/debugging. Doesn't have to be cross-browser.
>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> What does this mean?
>>
>> This means that if one browser support required functionality then I'll
>> use that specified browser in my case.
>
> Learn to think in terms of versions of implementations, not browsers.

Agreed. However before I start think in terms of versions of
implementations I need to figure out those implementations. Based on
your previous answer there is nothing I can find and use in my case
(below details).

>>>> Can someone suggest from where to start?
>>> No, because it is not possible.
>>
>> What a pity.
>
> <http://www.catb.org/~esr/faqs/smart-questions.htm...

Let me rephrase it. When I run the web application in the browser
environment then I'd like to check how many times every
functions/methods are called. The simplest way is to add console.count
(https://developer.mozilla.org/en-US/docs/Web/API/con...) to
every function/method.

However, I think that in reality it's not possible to do that because
then changes needs to be done everywhere in the code. So, I thought that
it would be better to "wrap" every function/method globally (not sure if
I described it correctly) so that every call of function/method in web
application first will call custom function before and put information's
from console.count. In that way I could measure how many times every
function/method is called. That's my goal.

--
Cezary Tomczyk
http://www.ct...

Thomas 'PointedEars' Lahn

6/13/2014 11:57:00 PM

0

Cezary Tomczyk wrote:

> 2014-06-13 19:01, Thomas 'PointedEars' Lahn wrote:
>> Cezary Tomczyk wrote:
>>> 2014-06-13 16:56, Thomas 'PointedEars' Lahn wrote:
>>>> Cezary Tomczyk wrote:
>>>>> I am looking for a solution where I can bind custom function to the
>>>>> all Function objects. Whenever any function/method will be called I'd
>>>>> like to call my custom function. I am going to use it only for
>>>>> testing/debugging. Doesn't have to be cross-browser.
>>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>> What does this mean?
>>>
>>> This means that if one browser support required functionality then I'll
>>> use that specified browser in my case.
>>
>> Learn to think in terms of versions of implementations, not browsers.
>
> Agreed. However before I start think in terms of versions of
> implementations I need to figure out those implementations

So you should ask â??Which implementation X supports feature Y?â? and then
â??Which browser Z supports implementation X?â?, and not â??Which browser Z
supports feature Y?�

> Based on your previous answer there is nothing I can find and use in my
> case (below details).

Do not jump to conclusions. Your case was not at all clear.

> Let me rephrase it. When I run the web application in the browser
> environment then I'd like to check how many times every
> functions/methods are called. The simplest way is to add console.count
> (https://developer.mozilla.org/en-US/docs/Web/API/con...) to
> every function/method.

Thanks, I did not know of that method.

> However, I think that in reality it's not possible to do that because
> then changes needs to be done everywhere in the code. So, I thought that
> it would be better to "wrap" every function/method globally (not sure if
> I described it correctly) so that every call of function/method in web
> application first will call custom function before and put information's
> from console.count. In that way I could measure how many times every
> function/method is called. That's my goal.

It is possible to wrap all *your* functions (that you *know*) simply by
replacing them (I do something similar in jsx.dom.addEventListener() in
order to emulate EventTarget::addEventListener() when unavailable):

var myFunction = function () {
console.log("myFunction");
};

/**
* Adds a call counter to a function.
*
* NOTE: Must pass object reference and property name for a general
* solution because there is no call-by-reference
*
* @param {Object} obj
* @param {String} propName
* @return {Function}
* Decorated function
*/
function addCounter (obj, propName)
{
var original_function = obj[propName];

if (typeof original_function != "function")
{
throw new TypeError(
"addCounter: obj[propName] must refer to a function");
}

var decorated = function () {
console.count("myFunction");
original_function.apply(this, arguments);
};

obj[propName] = decorated;

return decorated;
}

/*
* Example: in global context; cannot generally decorate local functions
*/
addCounter(this, "myFunction");

However, as I have (re)discovered today thanks to your posting, it is easier
to use the Firebug profiler. Go to the â??Consoleâ? tab, select â??Profileâ?, and
select â??Profileâ? again when you are done. The second column of the profile
shows the number of times each function/method was called.

<https://getfirebug.com/java...

However, note that you will be only profiling the behavior of your code with
Mozilla JavaScript.

I could not find a similar feature in Iceweasel 30â??s built-in Web Developer
Tools or in Chrome Developer Tools in Chromium 34.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Thomas 'PointedEars' Lahn

6/14/2014 1:56:00 PM

0

Thomas 'PointedEars' Lahn wrote:

> Cezary Tomczyk wrote:
>> However, I think that in reality it's not possible to do that because
>> then changes needs to be done everywhere in the code. So, I thought that
>> it would be better to "wrap" every function/method globally (not sure if
>> I described it correctly) so that every call of function/method in web
>> application first will call custom function before and put information's
>> from console.count. In that way I could measure how many times every
>> function/method is called. That's my goal.
>
> It is possible to wrap all *your* functions (that you *know*) simply by
> replacing them (I do something similar in jsx.dom.addEventListener() in
> order to emulate EventTarget::addEventListener() when unavailable):
>
> var myFunction = function () {
> console.log("myFunction");
> };
>
> /**
> * Adds a call counter to a function.
> *
> * NOTE: Must pass object reference and property name for a general
> * solution because there is no call-by-reference
> *
> * @param {Object} obj
> * @param {String} propName
> * @return {Function}
> * Decorated function
> */
> function addCounter (obj, propName)
> {
> var original_function = obj[propName];
>
> if (typeof original_function != "function")
> {
> throw new TypeError(
> "addCounter: obj[propName] must refer to a function");
> }
>
> var decorated = function () {
> console.count("myFunction");
> original_function.apply(this, arguments);
> };
>
> obj[propName] = decorated;
>
> return decorated;
> }
>
> /*
> * Example: in global context; cannot generally decorate local functions
> */
> addCounter(this, "myFunction");

Slight improvement (untested):

/**
* Decorates a function with code to be executed before and/or after
* it is called.
*
* @param {Object|Function} obj
* @param {String|Null|Undefined} propName
* @param {Function} before
* Code to be executed before the original function. Called with
* the same <code>this</code> value and arguments as the original
* function.
* @param {Function} after (optional)
* Code to be executed after the original function. Called with
* the same <code>this</code> value as the original function.
* The arguments lists consists of the return value of the
* original function followed by its argument list.
* @return {Function} Decorated function
*/
function decorate (obj, propName, before, after)
{
var original = (propName == null ? obj : obj[propName]);

if (typeof original != "function")
{
throw new TypeError(
"decorate: obj[propName] or obj must refer to a function");
}

var decorated = function () {
if (typeof before == "function")
{
before.apply(this, arguments);
}

var result = original.apply(this, arguments);

if (typeof after == "function")
{
after.apply(this, [result].concat([].slice.call(arguments)));
}
};

if (propName != null)
{
obj[propName] = decorated;
}

return decorated;
}

/*
* Example: in global context; cannot generally decorate local functions
*/
myFunction = decorate(myFunction, null, function () {
console.count("myFunction");
});

decorate(foo, "bar",
function () {
baz ();
},
function (result) {
bla(result);
});

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Cezary Tomczyk

6/16/2014 7:56:00 PM

0

2014-06-14 01:57, Thomas 'PointedEars' Lahn wrote:
> Cezary Tomczyk wrote:
[...]
>>> Learn to think in terms of versions of implementations, not browsers.
>>
>> Agreed. However before I start think in terms of versions of
>> implementations I need to figure out those implementations
>
> So you should ask â??Which implementation X supports feature Y?â? and then
> â??Which browser Z supports implementation X?â?, and not â??Which browser Z
> supports feature Y?�

Thanks.

>> Based on your previous answer there is nothing I can find and use in my
>> case (below details).
>
> Do not jump to conclusions. Your case was not at all clear.

Ok.

>> Let me rephrase it. When I run the web application in the browser
>> environment then I'd like to check how many times every
>> functions/methods are called. The simplest way is to add console.count
>> (https://developer.mozilla.org/en-US/docs/Web/API/con...) to
>> every function/method.
>
> Thanks, I did not know of that method.

You welcome.

[...]
> It is possible to wrap all *your* functions (that you *know*) simply by
> replacing them (I do something similar in jsx.dom.addEventListener() in
> order to emulate EventTarget::addEventListener() when unavailable):
[...]

I was thinking about same approach. However, I preferred something more
simpler so that it could be "applied once and works everywhere" without
even updating it in the future whenever main code will change.

> However, as I have (re)discovered today thanks to your posting, it is easier
> to use the Firebug profiler. Go to the â??Consoleâ? tab, select â??Profileâ?, and
> select â??Profileâ? again when you are done. The second column of the profile
> shows the number of times each function/method was called.
>
> <https://getfirebug.com/java...

That I know. However, above do not solving 2 problems:

1. What, if you want to measure it in the product across thousands of
testers around the world. Let's say the product is in testing phase.
Possible solution would be send the results periodically to the server
and having the web site where data from the server would be presented.

2. "Profile" measure performance in some very specific range: from start
click to end click. I'd like to measure it all the time during working
with application and see the results in real time.

> However, note that you will be only profiling the behavior of your code with
> Mozilla JavaScript.

And that's another problem.

> I could not find a similar feature in Iceweasel 30â??s built-in Web Developer
> Tools or in Chrome Developer Tools in Chromium 34.

Google Chrome contains "Profiles".

--
Cezary Tomczyk
http://www.ct...

Thomas 'PointedEars' Lahn

6/16/2014 9:26:00 PM

0

Cezary Tomczyk wrote:

> 2014-06-14 01:57, Thomas 'PointedEars' Lahn wrote:
>> Cezary Tomczyk wrote:
>>> Let me rephrase it. When I run the web application in the browser
>>> environment then I'd like to check how many times every
>>> functions/methods are called. The simplest way is to add console.count
>>> (https://developer.mozilla.org/en-US/docs/Web/API/con...) to
>>> every function/method.
>> Thanks, I did not know of that method.
>
> You welcome.
^are

> [...]
>> It is possible to wrap all *your* functions (that you *know*) simply by
>> replacing them (I do something similar in jsx.dom.addEventListener() in
>> order to emulate EventTarget::addEventListener() when unavailable):
> [...]
>
> I was thinking about same approach. However, I preferred something more
> simpler so that it could be "applied once and works everywhere" without
> even updating it in the future whenever main code will change.

Within limits, using object introspection, this approach can be adapted so
that it can be â??applied once and works everywhereâ?. See also my addendum.

>> <https://getfirebug.com/java...
>
> That I know.

It would be good if you published your findings in advance.

> 1. What, if you want to measure it in the product across thousands of
> testers around the world. Let's say the product is in testing phase.
> Possible solution would be send the results periodically to the server
> and having the web site where data from the server would be presented.

I do not see why it would be necessary to compare the number of calls around
the world. However, I cannot advise on hypothetical scenarios if I do not
know all relevant facts.

> 2. "Profile" measure performance in some very specific range: from start
> click to end click. I'd like to measure it all the time during working
> with application and see the results in real time.

There are console.profile() and console.profileEnd() (described on the
Firebug website). As for â??real timeâ?, you will probably have to find
another way. I would have expected console.profileEnd() to return the
results as an object.

>> I could not find a similar feature in Iceweasel 30â??s built-in Web
>> Developer Tools or in Chrome Developer Tools in Chromium 34.
>
> Google Chrome contains "Profiles".

Yes, but how can I get the *call count* that way?

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

ram

6/18/2014 12:26:00 AM

0

Cezary Tomczyk <cezary.tomczyk@gmail.com> writes:
>Subject: Bind custom function to the all Function objects

I read »to the all Function objects«
as »to all the function objects«.

>I am looking for a solution where I can bind custom function to the all
>Function objects. Whenever any function/method will be called I'd like
>to call my custom function. I am going to use it only for
>testing/debugging. Doesn't have to be cross-browser.
>Can someone suggest from where to start?

The program below calls

instrument( Object.getPrototypeOf( global.document ))

to add a call

global.console.log( "function " + key + " was called" );

in front of every defined function of the document
prototype.

When the document.writeln( 2 ); is then executed at the end,
the text

"function writeln was called"

is being written to the console.

Main.html =

<!DOCTYPE HTML><html><head><meta charset="UTF-8">
<title>Main</title><link rel="stylesheet" href="main.css">
</head><body><pre><code>
<script type="application/javascript;version=1.7" src="main.js"></script>
</code></pre></body></html>

main.css =

main.js =

"use strict";

const global = this;
const all = global;

function main()
{ "use strict";

const seen = global.Object.create( null );

const unseen = function( container, key, object )
{ "use strict";
if( typeof object === "function" )
{ let old = object;
container[ key ]= function()
{ global.console.log( "function " + key + " was called" );
return old.apply( this, arguments ); }}
else if( typeof object === "object" )
{ /* enumerate( object ); */ }
seen[ object ]= true; }

const enumerate = function( object )
{ "use strict";
if( typeof global.Object.getOwnPropertyNames === "function" )
{ const key = global.Object.getOwnPropertyNames( object );
const keyLength = key.length;
for( let i = 0; i < keyLength; ++i )
{ try
{ let entity = object[ key[ i ]];
if( !seen[ entity ])unseen( object, key[ i ], entity ); }
catch( exception ){} }}}

const instrument = function( object )
{ "use strict"; enumerate( object ); }

seen[ global.Object.getOwnPropertyNames ]= true;
instrument( Object.getPrototypeOf( global.document )); }

main();
document.writeln( 2 );