473,800 Members | 2,738 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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

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=functi on(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=functi on 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){b ody};

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
May 25 '06 #1
14 1650
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.
May 25 '06 #2
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
May 25 '06 #3
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=functi on 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.c o.uk/group/comp.lang.javas cript/browse_frm/thread/800641e55d59fb3 a/bfab46faf88c744 3?q=arguments.c allee&rnum=3#bf ab46faf88c7443>

The real question is 'why do you want to know'? Presumably for
debugging, where you could use arguments.calle e 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){b ody};


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

<URL:http://groups.google.c o.uk/group/comp.lang.javas cript/browse_frm/thread/d6460f64f222244 2/952287418c33ae6 c?q=arguments.c allee&rnum=7#95 2287418c33ae6c>

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.c om/faq/>
May 25 '06 #4

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

May 25 '06 #5
António Marques <m.**@sapo.pt > writes:
You can given them a name, as in

foo.ecks=functi on 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.toSt ring());
if (match) {
return match[1];
}
}

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

// test
var ns = addMethods({acc umulator:[]},
function add(n) {
this.accumulato r.push(n);
return this;
},
function sum() {
for(var i=0,r=0; i < this.accumulato r.length; i++) {
r+=this.accumul ator[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.d oFoo() { ... }
instead of
Foo.prototype.d oFoo = 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 - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
'Faith without judgement merely degrades the spirit divine.'
May 25 '06 #6
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.
May 25 '06 #7
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
May 25 '06 #8
pe**********@gm ail.com 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
May 25 '06 #9
Lasse Reichstein Nielsen wrote:
You can given them a name, as in

foo.ecks=functi on 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(targ et /*, functions...*/) {
for(var i = 1; i < arguments.lengt h; i++) {
var func = arguments[i];
if(typeof func == "function") {
var name = funcName(func);
if (name) {
target[name] = func;
}
}
}
return target;
}

// test
var ns = addMethods({acc umulator:[]},
function add(n) {
this.accumulato r.push(n);
return this;
},
function sum() {
for(var i=0,r=0; i < this.accumulato r.length; i++) {
r+=this.accumul ator[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.d oFoo() { ... }
instead of
Foo.prototype.d oFoo = 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
May 25 '06 #10

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

Similar topics

18
3053
by: Steven Bethard | last post by:
In the "empty classes as c structs?" thread, we've been talking in some detail about my proposed "generic objects" PEP. Based on a number of suggestions, I'm thinking more and more that instead of a single collections type, I should be proposing a new "namespaces" module instead. Some of my reasons: (1) Namespace is feeling less and less like a collection to me. Even though it's still intended as a data-only structure, the use cases...
15
5432
by: Stuart | last post by:
I work in a small company with developers who do not like to use "new" features when they find the old ones sufficient. e.g. given a choice between a class and a namespace, they'll pick class. Given a choice between naming functions at the global scope with subsystem prefixes (e.g. CTNode, CPNode) vs. namespaces (Time::Node, Place::Node) we'll use the global namespace. Prefixes they understand, and prefixes are short and do the job. ...
17
2078
by: clintonG | last post by:
Using 2.0 with Master Pages and a GlobalBaseClass for the content pages. I understand the easy part -- the hierarchical structure of a namespace naming convention -- but the 2.0 IDE does not write a signature for the developer and after getting a good start developing a 2.0 application I thought I should go through the code and start marking classes and with namespaces. I keep getting the following 'missing' error even when using a first...
36
4056
by: Wilfredo Sánchez Vega | last post by:
I'm having some issues around namespace handling with XML: >>> document = xml.dom.minidom.Document() >>> element = document.createElementNS("DAV:", "href") >>> document.appendChild(element) <DOM Element: href at 0x1443e68> >>> document.toxml() '<?xml version="1.0" ?>\n<href/>' Note that the namespace wasn't emitted. If I have PyXML,
0
9550
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10501
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10250
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10032
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9085
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5469
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5603
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4149
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3764
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.