Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Namespaces, or getting function foo.bar() declarations to work

Reply
Thread Tools

Namespaces, or getting function foo.bar() declarations to work

 
 
António Marques
Guest
Posts: n/a
 
      05-24-2006
Hi!

I don't think I've ever been here, so I assume I'm addressing a bunch of
nice people. Can you help me? I don't think there's a solution, but who
knows.

The thing is, picture a large project where you want some encapsulation.
But a lot of it being grouping of what would otherwise be static members
of the global namespace. So that instead of

fooEcks(), fooWye, fooZed()

you can have

foo.ecks(), foo.wye(), foo.zed()

with foo being a global variable.


Now this is perfectly possible, that I know, by declaring

var foo={} OR function foo(){}

and then having

foo.ecks=function(args){body}

or then by defining them inline, as in

var foo={ecks: function(args){body}}

However, in all of these, the functions created are anonymous. This may
make no difference, but I don't like it and it impacts debugging, when
you're trying to determine their name.

You can given them a name, as in

foo.ecks=function ecks(args){body}

But this is error prone, since you have to keep the two names in sync,
and that is a sure road to damnation.


It turns out that in IE6, if you do

function foo(){}; // with 'var foo' it won't work
function foo.ecks(args){body};

the browser does create a member of foo, named ecks, which is then your
foo.ecks function. I may be missing something, but this seems great to
me, in absence of alternatives (my preferred would be simply that
internal named functions were public).

But as it is, neither Opera nor Gecko accept this notation. And for the
life of me, I haven't been able to figure out any other way to define a
public static member (though instance members would have the same
problem) that isn't anonymous without referring its name twice. Needless
to say, something like

var foo={ecks: fooEcks};
function fooEcks(args){body};

isn't the solution because it keeps the repetition (though this time it
could be automated to avoid errors - but notice that then we're going
far away from the natural constructs of the language), clutters the
global namespace anyhow, and probably creates all sorts of scope
problems (otherwise, we may just delete all of those references after
reassigning the functions to their namespace, but somehow this doesn't
look like a sensible solution).

So, any ideas? Thanks,
--
am

laurus : rhodophyta : brezoneg : smalltalk : stargate
 
Reply With Quote
 
 
 
 
Richard Cornford
Guest
Posts: n/a
 
      05-25-2006
António Marques wrote:
<snip>
> However, in all of these, the functions created are anonymous.
> This may make no difference, but I don't like it and it impacts
> debugging, when you're trying to determine their name.

<snip>

This assumption appears to be the crux of your issue, but you have not
explained or justified it. Most javascript error reports output line
numbers (at minimum) so I don't see any need to have a name associated
with the function for debugging.

Richard.


 
Reply With Quote
 
 
 
 
António Marques
Guest
Posts: n/a
 
      05-25-2006
Richard Cornford wrote:

>> However, in all of these, the functions created are anonymous.
>> This may make no difference, but I don't like it and it impacts
>> debugging, when you're trying to determine their name.

>
> This assumption appears to be the crux of your issue, but you have not
> explained or justified it. Most javascript error reports output line
> numbers (at minimum) so I don't see any need to have a name associated
> with the function for debugging.


It's not an assumption, they really are anonymous. But you are right
that it it the crux of the issue: both that I can't extract a name for
them, and more generally that they don't have one. If I could get a name
I'd be happy, even if the function were anonymous the same. In fact, I
wouldn't mind at all, since for instance I'd like internal functions to
yield the name of their context and not their own:

function foo()
{
function bar()
{
debug('hello', 1, 'a')
}
}

And function debug would output something like

'10:04:55 [foo] hello, 1, a'

As to the why, javascript error reports are more or less the equivalent
of exception stack traces. They can be informative, and a script
debugger may help hunt down and fix an error, but debug outputs have
their own value.

Maybe there's something hidden in the function object that I haven't
discovered yet.
--
am

laurus : rhodophyta : brezoneg : smalltalk : stargate
 
Reply With Quote
 
RobG
Guest
Posts: n/a
 
      05-25-2006
António Marques wrote:
> Hi!
>
> I don't think I've ever been here, so I assume I'm addressing a bunch of
> nice people. Can you help me? I don't think there's a solution, but who
> knows.
>
> The thing is, picture a large project where you want some encapsulation.
> But a lot of it being grouping of what would otherwise be static members
> of the global namespace. So that instead of


[...]

> However, in all of these, the functions created are anonymous. This may
> make no difference, but I don't like it and it impacts debugging, when
> you're trying to determine their name.
>
> You can given them a name, as in
>
> foo.ecks=function ecks(args){body}
>
> But this is error prone, since you have to keep the two names in sync,
> and that is a sure road to damnation.


This question is asked from time to time, you can try searching the
archives for answers but you've already summarised the case. Try this
thread:

<URL:http://groups.google.co.uk/group/comp.lang.javascript/browse_frm/thread/800641e55d59fb3a/bfab46faf88c7443?q=arguments.callee&rnum=3#bfab46f af88c7443>

The real question is 'why do you want to know'? Presumably for
debugging, where you could use arguments.callee to get the name of the
function. The "best" solution is the one you've already discounted:

foo.ecks = function ecks(...){...};

Another 'solution' is to pass the function name to the function when you
call it.

It is highly desirable that stuff specific to debugging can be easily
removed for production code - implementing either of the above will make
that very difficult.


> It turns out that in IE6, if you do
>
> function foo(){}; // with 'var foo' it won't work
> function foo.ecks(args){body};
>
> the browser does create a member of foo, named ecks, which is then your
> foo.ecks function. I may be missing something, but this seems great to
> me, in absence of alternatives (my preferred would be simply that
> internal named functions were public).


Do you mean:

function foo(){
function bar(){}
}
bar(); // Error: bar is not defined.

What would be the point of declaring a function inside a function object
(i.e. creating a 'private member') if it was then public?


> But as it is, neither Opera nor Gecko accept this notation. And for the
> life of me, I haven't been able to figure out any other way to define a
> public static member (though instance members would have the same
> problem) that isn't anonymous without referring its name twice. Needless
> to say, something like
>
> var foo={ecks: fooEcks};
> function fooEcks(args){body};


Read this post by Richard Cornford regarding class concepts (public,
private, etc.):

<URL:http://groups.google.co.uk/group/comp.lang.javascript/browse_frm/thread/d6460f64f2222442/952287418c33ae6c?q=arguments.callee&rnum=7#9522874 18c33ae6c>

It may seem a little obtuse in regard to your question, but it's a good
read anyway.


--
Rob
Group FAQ: <URL:http://www.jibbering.com/faq/>
 
Reply With Quote
 
petermichaux@gmail.com
Guest
Posts: n/a
 
      05-25-2006

António Marques wrote:
>
> The thing is, picture a large project where you want some encapsulation.
> But a lot of it being grouping of what would otherwise be static members
> of the global namespace. So that instead of
>
> fooEcks(), fooWye, fooZed()


What is your objection to this method?


> you can have
>
> foo.ecks(), foo.wye(), foo.zed()


Richard explained to me just yesterday that this is a bad idea because
JavaScript is not compiled but rather interpreted. He wrote

"Simulated namespaces are a very questionable notion. In other language
the namespaces are resolved when the code is compiled. Javascript must
resolve those long property accessors each and every time they are
used."

You can find the whole post in the archives of this newsgroup.


> However, in all of these, the functions created are anonymous. This may
> make no difference, but I don't like it


maybe sometimes it is worth going with the flow of the language

> and it impacts debugging, when
> you're trying to determine their name.


Firefox spits out line numbers which makes it no problem.

Peter

 
Reply With Quote
 
Lasse Reichstein Nielsen
Guest
Posts: n/a
 
      05-25-2006
António Marques <(E-Mail Removed)> writes:

> You can given them a name, as in
>
> foo.ecks=function ecks(args){body}
>
> But this is error prone, since you have to keep the two names in sync,
> and that is a sure road to damnation.


Then only write it once:
---
// extract name from function's toString
function funcName(func) {
var match = /^\s*function\s+([\w$]+)[^\w$]/.exec(func.toString());
if (match) {
return match[1];
}
}

// extend object with named methods
function addMethods(target /*, functions...*/) {
for(var i = 1; i < arguments.length; i++) {
var func = arguments[i];
if(typeof func == "function") {
var name = funcName(func);
if (name) {
target[name] = func;
}
}
}
return target;
}

// test
var ns = addMethods({accumulator:[]},
function add(n) {
this.accumulator.push(n);
return this;
},
function sum() {
for(var i=0,r=0; i < this.accumulator.length; i++) {
r+=this.accumulator[i];
}
return r;
});

alert(ns.add(2).add(40).sum()); // alerts 42
---

> It turns out that in IE6, if you do
>
> function foo(){}; // with 'var foo' it won't work
> function foo.ecks(args){body};
>
> the browser does create a member of foo, named ecks, which is then
> your foo.ecks function.


Nice idea, especially for extending prototypes:
function Foo.prototype.doFoo() { ... }
instead of
Foo.prototype.doFoo = function doFoo() {...}

But it's completely non-standard, so only viable for scripting
specific known browsers and not for internet use.

/L
--
Lasse Reichstein Nielsen - http://www.velocityreviews.com/forums/(E-Mail Removed)
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
 
Reply With Quote
 
Richard Cornford
Guest
Posts: n/a
 
      05-25-2006
António Marques wrote:
> Richard Cornford wrote:
>>> However, in all of these, the functions created are
>>> anonymous. This may make no difference, but I don't
>>> like it and it impacts debugging, when you're trying
>>> to determine their name.

>>
>> This assumption appears to be the crux of your issue, but
>> you have not explained or justified it. Most javascript
>> error reports output line numbers (at minimum) so I don't
>> see any need to have a name associated with the function
>> for debugging.

>
> It's not an assumption, they really are anonymous. ...

<snip>

That was not the assumption. The assumption was that using anonymous
functions would impact debugging. It is an assumption as anonymous
functions are common on non-trivial javascript and if their use really
was a problem when debugging that would have been noticed by now.

> function foo()
> {
> function bar()
> {
> debug('hello', 1, 'a')
> }
> }
>
> And function debug would output something like
>
> '10:04:55 [foo] hello, 1, a'

<snip>

The 'hello' got into that output because you put it there, why not put
in the information that tells you what you need in the output, like
something that tells you the context of the debug call?

Richrd.


 
Reply With Quote
 
António Marques
Guest
Posts: n/a
 
      05-25-2006
RobG wrote:

> (stuff)


Thank you for the references, Rob.
Some things are just hard to find out other than asking them to a
knowledgeable group (it's easy enough to find the answer to 'how to do
X?', but not necessarily so when the question amounts to 'in how many
ways can X be done?'), and you seem knowledgeable alright (this language
is so generally misunderstood that one must be careful).

>> It turns out that in IE6, if you do
>>
>> function foo(){}; // with 'var foo' it won't work
>> function foo.ecks(args){body};
>>
>> the browser does create a member of foo, named ecks, which is then
>> your foo.ecks function. I may be missing something, but this seems
>> great to me, in absence of alternatives (my preferred would be simply
>> that internal named functions were public).

>
> Do you mean:
>
> function foo(){
> function bar(){}
> }
> bar(); // Error: bar is not defined.


( Actually foo.bar() )

> What would be the point of declaring a function inside a function object
> (i.e. creating a 'private member') if it was then public?


I'd like it to be public. To define a private function, one could use a
private variable and assign a function to it.
--
am

laurus : rhodophyta : brezoneg : smalltalk : stargate
 
Reply With Quote
 
António Marques
Guest
Posts: n/a
 
      05-25-2006
(E-Mail Removed) wrote:

>> The thing is, picture a large project where you want some
>> encapsulation. But a lot of it being grouping of what would
>> otherwise be static members of the global namespace. So that
>> instead of
>>
>> fooEcks(), fooWye, fooZed()

>
> What is your objection to this method?


And:

>> you can have
>>
>> foo.ecks(), foo.wye(), foo.zed()

>
> Richard explained to me just yesterday that this is a bad idea
> because JavaScript is not compiled but rather interpreted (...)


Thanks for the pointer - I'll follow this on the other thread.

>> and it impacts debugging, when you're trying to determine their
>> name.

>
> Firefox spits out line numbers which makes it no problem.


But debugging in particular and logging in general is so much more than
looking at exception reports.
--
am

laurus : rhodophyta : brezoneg : smalltalk : stargate
 
Reply With Quote
 
António Marques
Guest
Posts: n/a
 
      05-25-2006
Lasse Reichstein Nielsen wrote:

>> You can given them a name, as in
>>
>> foo.ecks=function ecks(args){body}
>>
>> But this is error prone, since you have to keep the two names in sync,
>> and that is a sure road to damnation.

>
> Then only write it once:
> (...)
> // extend object with named methods
> function addMethods(target /*, functions...*/) {
> for(var i = 1; i < arguments.length; i++) {
> var func = arguments[i];
> if(typeof func == "function") {
> var name = funcName(func);
> if (name) {
> target[name] = func;
> }
> }
> }
> return target;
> }
>
> // test
> var ns = addMethods({accumulator:[]},
> function add(n) {
> this.accumulator.push(n);
> return this;
> },
> function sum() {
> for(var i=0,r=0; i < this.accumulator.length; i++) {
> r+=this.accumulator[i];
> }
> return r;
> });


Hey, this looks great! But will the final code behave just in the same
way as if it were defined with

var ns = {accumulator:[]};
ns.add = function add(n) { ... };
ns.sum = function add(n) { ... };

?
I see it does in the test given, but I ask this because of the scope
chain - it seems to me that the first scope in both cases is the owner
of var ns, but is it really?

>> It turns out that in IE6, if you do
>>
>> function foo(){}; // with 'var foo' it won't work
>> function foo.ecks(args){body};
>>
>> the browser does create a member of foo, named ecks, which is then
>> your foo.ecks function.

>
> Nice idea, especially for extending prototypes:
> function Foo.prototype.doFoo() { ... }
> instead of
> Foo.prototype.doFoo = function doFoo() {...}
>
> But it's completely non-standard, so only viable for scripting
> specific known browsers and not for internet use.


I was very unhappy when I found out it was IE specific.
--
am

laurus : rhodophyta : brezoneg : smalltalk : stargate
 
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
Functions don't work in declarations section davehigton VHDL 2 12-24-2008 09:07 AM
Won't work without useless declarations Lars Eighner C Programming 9 09-18-2007 05:34 PM
const in function declarations TechCrazy C++ 6 04-24-2005 09:13 PM
function declarations, global/within a function? Douglas C Programming 2 07-05-2004 08:54 PM
Local function declarations Dave Theese C++ 1 09-05-2003 05:58 AM



Advertisments