www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How do you think about the flooding of bracket?

reply "Boris Wang" <nano.kago hotmail.com> writes:
First, now, in a function of D, we can make netsted structure, nested 
function and versioned code block, so much brackets, which are not code 
block ,in the code sequence.

Second, the use of colon and bracket for private/public, static and version 
keyword, make the judge of access level and storage type is difficult.

  class aClass
  {
    public:
      .
      .
      ...three pages
      .
      void func( ...)
      {

       }
     .
     .
     static:
      .
      ... four pages
      .
      int gotit(){...}

How do you think about all these ?
Jun 15 2006
next sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
I think technically these { things } are called curly braces.
I love them. 100x times better than begin end. IMO, they make 
function/class bodies standout.

As for the second question, well, for the example you've given, I'd 
blame the coder who wrote it.

Boris Wang wrote:
 First, now, in a function of D, we can make netsted structure, nested 
 function and versioned code block, so much brackets, which are not code 
 block ,in the code sequence.
 
 Second, the use of colon and bracket for private/public, static and version 
 keyword, make the judge of access level and storage type is difficult.
 
   class aClass
   {
     public:
       .
       .
       ...three pages
       .
       void func( ...)
       {
 
        }
      .
      .
      static:
       .
       ... four pages
       .
       int gotit(){...}
 
 How do you think about all these ?
 
 

Jun 15 2006
next sibling parent Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
Hasan Aljudy wrote:
 I think technically these { things } are called curly braces.

The Americans call them "braces", the British prefer "curly brackets". "Curly braces" is common, but it's redundant, since there's only one type of braces.
Jun 15 2006
prev sibling next sibling parent reply "BLS" <lietz wanadoo.fr> writes:
Hi Hasan,
using  {}      instead of          begin end                   is more a
matter of taste. Since I am comming form Oberon/Modula i prefer (of course)
the last one, but I think using {} in D is more a political
decision.(convincing Cpp and Java nerds) . I think D respective Walter has
borrowed some ideas from the Wirth s languages family, let us name the
module concept , nestested functions just to name some items. So what makes
me wonder that the enclosing concept,  is not part of D.
a simple  example from Modula 2:

Module  Primes;
FROM InOut IMPORT Writeln, ......;

  PROCEDURE abc
  ...
     PROCEDURE xyz
        ....
    END xyz
  ....
  END abc
END  Primes

Have a look at then END declarations: I found them quit usefull and the code
more readable, at least in deep nested functions. But perhaps :
int xyz()
{
}xyz
looks a bit too strange. <g>
Just my 2 cents
Bjoern.

"Hasan Aljudy" <hasan.aljudy gmail.com> schreef in bericht
news:e6rhq4$1ce3$1 digitaldaemon.com...
 I think technically these { things } are called curly braces.
 I love them. 100x times better than begin end. IMO, they make
 function/class bodies standout.


Jun 15 2006
parent reply Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
BLS wrote:
 a simple  example from Modula 2:
 
 Module  Primes;
 FROM InOut IMPORT Writeln, ......;
 
   PROCEDURE abc
   ...
      PROCEDURE xyz
         ....
     END xyz
   ....
   END abc
 END  Primes
 
 Have a look at then END declarations: I found them quit usefull and the code
 more readable, at least in deep nested functions.
 

I find something like that gets very annoying quickly, when "PROCEDURE xyz" is one or two lines long. Imagine something like (mixed-syntax pseudocode): PROCEDURE foo(int x) PROCEDURE bar PROCEDURE baz return 6; END baz x += baz(); END bar if (x) BEGIN while (x < 10) BEGIN bar(); foo(x); END END return x; END foo At least to me, the extraneous foo/bar/baz in the above make it harder to quickly read and understand. In my mind, when things start to get unreadable due to them spanning many lines and/or there being a lot of nesting, you can just use a comment at the ending curly bracket: void foo() { ... } // end foo()
Jun 15 2006
next sibling parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Deewiant wrote:
 In my mind, when things start to get unreadable due to them spanning many lines
 and/or there being a lot of nesting, you can just use a comment at the ending
 curly bracket:
 
 void foo() {
 	...
 } // end foo()

This is generally what I do, except I don't say "end" because I already know that -- why else would I document a closing brace? ;) Instead I generally put a reminder of the type of the 'foo' I'm ending: function, or class, or struct, or whatever. So in the case above, I'd write `// function foo`. -- Chris Nicholson-Sauls
Jun 15 2006
parent BCS <BCS pathlink.com> writes:
This looks like a good place for a code scanning tool. It would scan 
code and at each "}" find what the matching "{" is coming from and if 
their is already a label verify that it is correct, otherwise insert a 
label. Might help catch incorrectly matched braces which is what I'm 
guessing the "END label" construct is trying to do.


Chris Nicholson-Sauls wrote:
 Deewiant wrote:
 
 In my mind, when things start to get unreadable due to them spanning 
 many lines
 and/or there being a lot of nesting, you can just use a comment at the 
 ending
 curly bracket:

 void foo() {
     ...
 } // end foo()

This is generally what I do, except I don't say "end" because I already know that -- why else would I document a closing brace? ;) Instead I generally put a reminder of the type of the 'foo' I'm ending: function, or class, or struct, or whatever. So in the case above, I'd write `// function foo`. -- Chris Nicholson-Sauls

Jun 15 2006
prev sibling parent reply "BLS" <lietz wanadoo.fr> writes:
"Deewiant" <deewiant.doesnotlike.spam gmail.com> schreef in bericht
news:e6rno9$1ju8$1 digitaldaemon.com...
 I find something like that gets very annoying quickly, when "PROCEDURE


 one or two lines long. Imagine something like (mixed-syntax pseudocode):

Hi Deewiant, a two line inner function seems , at least to me, to be a quit seldom used construction. But anyway, i guess exept me nobody is interested in such kind of language extension. and it will be nearly impossible to keep the D compiler compatible with ancient versions.. kind regards and thanks for your feedback. bjoern
 PROCEDURE foo(int x)
 PROCEDURE bar
 PROCEDURE baz
 return 6;
 END baz
 x += baz();
 END bar
 if (x) BEGIN
 while (x < 10) BEGIN
 bar();
 foo(x);
 END
 END
 return x;
 END foo

 At least to me, the extraneous foo/bar/baz in the above make it harder to
 quickly read and understand.

 In my mind, when things start to get unreadable due to them spanning many

 and/or there being a lot of nesting, you can just use a comment at the

 curly bracket:

 void foo() {
 ...
 } // end foo()

Jun 15 2006
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
BLS wrote:
 "Deewiant" <deewiant.doesnotlike.spam gmail.com> schreef in bericht
 news:e6rno9$1ju8$1 digitaldaemon.com...
 I find something like that gets very annoying quickly, when "PROCEDURE


 one or two lines long. Imagine something like (mixed-syntax pseudocode):

Hi Deewiant, a two line inner function seems , at least to me, to be a quit seldom used construction.

Well, that depends on your coding style, really. Personally, I prefer to write lots of small, well-defined functions. If I can't fit a whole function's flow into my head at once, then I know I need to break it up. One interesting approach to this problem I've seen is in Nemerle: it supports both C-style syntax and, with the flip of a compiler switch, Python-style indenting. Mmm... cake. -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Jun 15 2006
next sibling parent reply "BLS" <lietz wanadoo.fr> writes:
Hi Daniel,
Python style indenting is ...
what I would really like to see in D. but let us keep realistic...
in fact nothing new, i think also the very first dbase interpreter allows
it.
and
Nowadays the most 4GLs are using a pascal like language without {},
respective  begin end,  or even ;
From a compiler designers view it means a lot of additional work.

Thanks to Eric Andersons message I have had today the very first look on
Nemerle. Looks clean, modern and usable.(and the most important point)
readable.
Bjoern


"Daniel Keep" <daniel.keep.lists gmail.com> schreef in bericht
news:e6rufj$1t3d$1 digitaldaemon.com...
 BLS wrote:
 "Deewiant" <deewiant.doesnotlike.spam gmail.com> schreef in bericht
 news:e6rno9$1ju8$1 digitaldaemon.com...
 I find something like that gets very annoying quickly, when "PROCEDURE


 one or two lines long. Imagine something like (mixed-syntax



 Hi Deewiant,
 a two line inner function seems , at least to me, to be a quit seldom


 construction.

Well, that depends on your coding style, really. Personally, I prefer to write lots of small, well-defined functions. If I can't fit a whole function's flow into my head at once, then I know I need to break it up. One interesting approach to this problem I've seen is in Nemerle: it supports both C-style syntax and, with the flip of a compiler switch, Python-style indenting. Mmm... cake. -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/

Jun 15 2006
parent "Andrei Khropov" <andkhropov nospam_mtu-net.ru> writes:
BLS wrote:

 Hi Daniel,
 Python style indenting is ...
 what I would really like to see in D. but let us keep realistic...
 in fact nothing new, i think also the very first dbase interpreter allows
 it.
 and
 Nowadays the most 4GLs are using a pascal like language without {},
 respective  begin end,  or even ;
 From a compiler designers view it means a lot of additional work.
 
 Thanks to Eric Andersons message I have had today the very first look on
 Nemerle. Looks clean, modern and usable.(and the most important point)
 readable.

Well, khm, I suppose it was my message. Nemerle developers also have possibility to write in Python-like syntax in mind: http://nemerle.org/Open_projects#Python-like_syntax_front-end They estimate it to be fairly easy to integrate but of course if it is done it will mean some kind of split among developers on a style basis. So maybe to stick with a single syntax is better for the sake of consistency and code exchange. P.S. I don't think we should discuss it further here because it's D forum after all. -- AKhropov
Jun 15 2006
prev sibling parent reply Georg Wrede <georg.wrede nospam.org> writes:
Daniel Keep wrote:
 
 BLS wrote:
 
 "Deewiant" <deewiant.doesnotlike.spam gmail.com> schreef in bericht
  news:e6rno9$1ju8$1 digitaldaemon.com...
 
 I find something like that gets very annoying quickly, when
 "PROCEDURE


xyz" is
 one or two lines long. Imagine something like (mixed-syntax
 pseudocode):

Hi Deewiant, a two line inner function seems , at least to me, to be a quit seldom used construction.

Well, that depends on your coding style, really. Personally, I prefer to write lots of small, well-defined functions. If I can't fit a whole function's flow into my head at once, then I know I need to break it up.

Kudos, Daniel, for saying that!! I used to write long functions, but then I got a peek at Turbo Pascal 5.5 library source code, and I was simply astounded. Very few of the functions (or procedures) were more than 5 lines of [actual] code! I think this was the reason why Borland was able to release new versions of their Pascal and the IDE, quite often, and had very few bugs in them. This coding style is actually encouraged in Java documentation, and the compiler is supposed to optimise away much of the "unneeded function calls", and do automatic inlining of stuff that gets only used in a couple of places -- by default. From that day on, I myself could tackle much bigger projects, and modifying and rewriting became pleasant, instead of being a nightmare. (I think programming is taught in such a way that people don't get in a habit of, or see the value in, keeping functions short.) Another thing they used was function and identifier names that let the naive reader instantly see what was going on. (Sure, it takes "more ink", but when somebody else has to edit your code one day, the difference is like night and day.)
 One interesting approach to this problem I've seen is in Nemerle: it 
 supports both C-style syntax and, with the flip of a compiler switch,
  Python-style indenting.

Dot Net, anyone? ;-(
Jun 16 2006
next sibling parent Hasan Aljudy <hasan.aljudy gmail.com> writes:
Georg Wrede wrote:
 
 
 Daniel Keep wrote:
 
 BLS wrote:

 "Deewiant" <deewiant.doesnotlike.spam gmail.com> schreef in bericht
  news:e6rno9$1ju8$1 digitaldaemon.com...

 I find something like that gets very annoying quickly, when
 "PROCEDURE


xyz" is
 one or two lines long. Imagine something like (mixed-syntax
 pseudocode):

Hi Deewiant, a two line inner function seems , at least to me, to be a quit seldom used construction.

Well, that depends on your coding style, really. Personally, I prefer to write lots of small, well-defined functions. If I can't fit a whole function's flow into my head at once, then I know I need to break it up.

Kudos, Daniel, for saying that!!

ditto! That's exactly what I do.
 
 I used to write long functions, but then I got a peek at Turbo Pascal 
 5.5 library source code, and I was simply astounded. Very few of the 
 functions (or procedures) were more than 5 lines of [actual] code!
 
 I think this was the reason why Borland was able to release new versions 
 of their Pascal and the IDE, quite often, and had very few bugs in them. 
 This coding style is actually encouraged in Java documentation, and the 
 compiler is supposed to optimise away much of the "unneeded function 
 calls", and do automatic inlining of stuff that gets only used in a 
 couple of places -- by default.
 
  From that day on, I myself could tackle much bigger projects, and 
 modifying and rewriting became pleasant, instead of being a nightmare.
 
 (I think programming is taught in such a way that people don't get in a 
 habit of, or see the value in, keeping functions short.)
 
 Another thing they used was function and identifier names that let the 
 naive reader instantly see what was going on. (Sure, it takes "more 
 ink", but when somebody else has to edit your code one day, the 
 difference is like night and day.)
 
 One interesting approach to this problem I've seen is in Nemerle: it 
 supports both C-style syntax and, with the flip of a compiler switch,
  Python-style indenting.

Dot Net, anyone? ;-(

Jun 16 2006
prev sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Georg Wrede wrote:
 
 
 Daniel Keep wrote:
 [snip]

 Personally, I prefer to write lots of small, well-defined functions.
 If I can't fit a whole function's flow into my head at once, then I
 know I need to break it up.

Kudos, Daniel, for saying that!! I used to write long functions, but then I got a peek at Turbo Pascal 5.5 library source code, and I was simply astounded. Very few of the functions (or procedures) were more than 5 lines of [actual] code!

For me, it was Python that really changed how I code. The first two times I tried to pick up Python, I just dismissed it as being another "weird" language. The third time I tried, I finally groked functional programming. All of a sudden, I could express complex ideas using lists and functions, combining them with a few simple operations. Python's actually changed many aspects of my coding style, mostly for the better. Java, on the other hand, taught me to hate identifiersWhichAreFullAndGramaticallyCompleteEnglishSentences ;) -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Jun 16 2006
prev sibling parent "Boris Wang" <nano.kago hotmail.com> writes:
The problem is not about {} and BEGIN/END.

Because in D, we can define the function when declare, so the syntax, such 
private: static: public{}, should be discarded.

"Hasan Aljudy" <hasan.aljudy gmail.com> 
??????:e6rhq4$1ce3$1 digitaldaemon.com...
I think technically these { things } are called curly braces.
 I love them. 100x times better than begin end. IMO, they make 
 function/class bodies standout.

 As for the second question, well, for the example you've given, I'd blame 
 the coder who wrote it.

 Boris Wang wrote:
 First, now, in a function of D, we can make netsted structure, nested 
 function and versioned code block, so much brackets, which are not code 
 block ,in the code sequence.

 Second, the use of colon and bracket for private/public, static and 
 version keyword, make the judge of access level and storage type is 
 difficult.

   class aClass
   {
     public:
       .
       .
       ...three pages
       .
       void func( ...)
       {

        }
      .
      .
      static:
       .
       ... four pages
       .
       int gotit(){...}

 How do you think about all these ?


Jun 15 2006
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 15 Jun 2006 17:37:41 +0800, Boris Wang wrote:

 First, now, in a function of D, we can make netsted structure, nested 
 function and versioned code block, so much brackets, which are not code 
 block ,in the code sequence.
 
 Second, the use of colon and bracket for private/public, static and version 
 keyword, make the judge of access level and storage type is difficult.

 ...

 How do you think about all these ?

I agree that the colon format for these qualifiers can lead to hard-to-maintain code because the scope of them is not as obvious. For that reason alone I avoid using them. I only use the single statement format and the braced format... private int someVar; static { int foo; int bar; } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 16/06/2006 11:49:54 AM
Jun 15 2006
next sibling parent reply "Boris Wang" <nano.kago hotmail.com> writes:
The only non-OT response, thanks!

I think this is a serious problem, a language should be helpful to produce 
readable, maintainable codes, and,  restrict the production of non-readable, 
non-maintainable codes.


"Derek Parnell" <derek psych.ward> 
??????:1simyhs9tx5zh.p1oewy5visyw$.dlg 40tude.net...
 On Thu, 15 Jun 2006 17:37:41 +0800, Boris Wang wrote:

 First, now, in a function of D, we can make netsted structure, nested
 function and versioned code block, so much brackets, which are not code
 block ,in the code sequence.

 Second, the use of colon and bracket for private/public, static and 
 version
 keyword, make the judge of access level and storage type is difficult.

 ...

 How do you think about all these ?

I agree that the colon format for these qualifiers can lead to hard-to-maintain code because the scope of them is not as obvious. For that reason alone I avoid using them. I only use the single statement format and the braced format... private int someVar; static { int foo; int bar; } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 16/06/2006 11:49:54 AM

Jun 15 2006
parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
Sometimes I have used something like this:

struct ObviouslyStaticStruct
{
static:
    // ...
}

Where everything in the struct is static.  But I don't do this often, 
mostly it's a poor man's namespace, e.g.:

struct constants
{
static:
    const int port = 21;
    const char[] name = "ftpd";
}

writefln(constants.name);

But, no, I'd not use them when it didn't apply to EVERYTHING, that's 
just too weird.  They have their uses, though, in my opinion.

-[Unknown]


 The only non-OT response, thanks!
 
 I think this is a serious problem, a language should be helpful to produce 
 readable, maintainable codes, and,  restrict the production of non-readable, 
 non-maintainable codes.
 
 
 "Derek Parnell" <derek psych.ward> 
 ??????:1simyhs9tx5zh.p1oewy5visyw$.dlg 40tude.net...
 On Thu, 15 Jun 2006 17:37:41 +0800, Boris Wang wrote:

 First, now, in a function of D, we can make netsted structure, nested
 function and versioned code block, so much brackets, which are not code
 block ,in the code sequence.

 Second, the use of colon and bracket for private/public, static and 
 version
 keyword, make the judge of access level and storage type is difficult.
 ...
 How do you think about all these ?

hard-to-maintain code because the scope of them is not as obvious. For that reason alone I avoid using them. I only use the single statement format and the braced format... private int someVar; static { int foo; int bar; } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 16/06/2006 11:49:54 AM


Jun 15 2006
parent reply Mike Parker <aldacron71 yahoo.com> writes:
Unknown W. Brackets wrote:

I've adopted a syntax where I only use the colon (:) form on protection 
attributes inside class/struct definitions. Outside, at module scope, I 
use brackets for for protection attributes. Other modifiers, such as 
static, final, abstract, I use inline. Version statements and multi-line 
debug statements all get brackets. extern statements get colons.

It's a coding convention I've come to like. I would really hate to see 
the colon syntax removed because I find it to be much more readable in 
class definitions:

class MyClass
{
    private
    {
       void myFunc();
    }
}

With one function it's not so bad, just ugly. But with multiple methods, 
the colon form is much clearer to me. And I really wouldln't like being 
forced to put all of my protection attributes inline.

This is all just a matter of taste. Having optional coding styles is 
nice, I think. I understand where you're coming from, but there are many 
other ways to make code difficult to read. As I see it, this ain't broke 
so don't fix it.
Jun 15 2006
next sibling parent Mike Parker <aldacron71 yahoo.com> writes:
The previous post was suppose to be in response to Boris. And I wrote 
it, not Unknown ;)

Mike Parker wrote:
 Unknown W. Brackets wrote:
 
 I've adopted a syntax where I only use the colon (:) form on protection 
 attributes inside class/struct definitions. Outside, at module scope, I 
 use brackets for for protection attributes. Other modifiers, such as 
 static, final, abstract, I use inline. Version statements and multi-line 
 debug statements all get brackets. extern statements get colons.
 
 It's a coding convention I've come to like. I would really hate to see 
 the colon syntax removed because I find it to be much more readable in 
 class definitions:
 
 class MyClass
 {
    private
    {
       void myFunc();
    }
 }
 
 With one function it's not so bad, just ugly. But with multiple methods, 
 the colon form is much clearer to me. And I really wouldln't like being 
 forced to put all of my protection attributes inline.
 
 This is all just a matter of taste. Having optional coding styles is 
 nice, I think. I understand where you're coming from, but there are many 
 other ways to make code difficult to read. As I see it, this ain't broke 
 so don't fix it.

Jun 15 2006
prev sibling parent "Boris Wang" <nano.kago hotmail.com> writes:
"Mike Parker" <aldacron71 yahoo.com> 
??????:e6tjo6$106v$1 digitaldaemon.com...
 Unknown W. Brackets wrote:

 I've adopted a syntax where I only use the colon (:) form on protection 
 attributes inside class/struct definitions. Outside, at module scope, I 
 use brackets for for protection attributes. Other modifiers, such as 
 static, final, abstract, I use inline. Version statements and multi-line 
 debug statements all get brackets. extern statements get colons.

 It's a coding convention I've come to like. I would really hate to see the 
 colon syntax removed because I find it to be much more readable in class 
 definitions:

 class MyClass
 {
    private
    {
       void myFunc();
    }
 }

 With one function it's not so bad, just ugly. But with multiple methods, 
 the colon form is much clearer to me. And I really wouldln't like being 
 forced to put all of my protection attributes inline.

 This is all just a matter of taste. Having optional coding styles is nice, 
 I think. I understand where you're coming from, but there are many other 
 ways to make code difficult to read. As I see it, this ain't broke so 
 don't fix it.

First, I post the thread, because neighter i like what, nor don't like what. Second, please think this problem in more complicated situation.
Jun 16 2006
prev sibling parent reply Don Clugston <dac nospam.com.au> writes:
Derek Parnell wrote:
 On Thu, 15 Jun 2006 17:37:41 +0800, Boris Wang wrote:
 
 First, now, in a function of D, we can make netsted structure, nested 
 function and versioned code block, so much brackets, which are not code 
 block ,in the code sequence.

 Second, the use of colon and bracket for private/public, static and version 
 keyword, make the judge of access level and storage type is difficult.

 ...

 How do you think about all these ?

I agree that the colon format for these qualifiers can lead to hard-to-maintain code because the scope of them is not as obvious. For that reason alone I avoid using them. I only use the single statement format and the braced format... private int someVar; static { int foo; int bar; }

Another important feature of the colon is that it can appear inside version{} blocks. You can't do this with the {} form. version(Windows) { extern(Windows): } else { extern(C): } // These are extern(Windows) on Windows systems, but // extern(C) on Linux. // For example, the MySQL functions behave this way. void func1(); void func2();
Jun 16 2006
parent Hasan Aljudy <hasan.aljudy gmail.com> writes:
Don Clugston wrote:
 Another important feature of the colon is that it can appear inside 
 version{} blocks. You can't do this with the {} form.
 
 version(Windows) {
 
   extern(Windows):
 
 } else {
 
   extern(C):
 
 }
 
 // These are extern(Windows) on Windows systems, but
 // extern(C) on Linux.
 // For example, the MySQL functions behave this way.
 void func1();
 void func2();
 

Hmm, sounds like a handy hack :)
Jun 16 2006