Re: Code Guidelines
- From: Garrett Smith <dhtmlkitchen@xxxxxxxxx>
- Date: Tue, 29 Dec 2009 17:04:03 -0800
Dmitry A. Soshnikov wrote:
On Dec 28, 9:25 am, Garrett Smith <dhtmlkitc...@xxxxxxxxx> wrote:Dmitry A. Soshnikov wrote:On Dec 27, 10:45 pm, Garrett Smith <dhtmlkitc...@xxxxxxxxx> wrote:[...]
[snip]
A public library that modifiesI understand, and told myself, that's this is the only (again - the
the built-ins can't really be trusted to work with other code.
only.) reason. And from this point of view, you should mention this
just as a warning for authors of libraries, but not as a rule for
programming on ECMAScript.
What I have as draft includes most of what I wrote in the last message.
The advice to create a top-level function advise creating a method as a
member of the global object, having the same problems.
Instead, a separate interface should be created. The interface should be
clearly defined, cohesive, and unlikely to conflict with other objects
that use the system.
Formally, there's no full protected "interface" from this point of
view. Will you name it `MyVeryOwnNamespace', and tomorrow, the same
name will be in all `libraries' and in ES itself. So, naming
collisions should not be treated as the main reason.
You can do that, but it doesn't fit what I think of as OOP. It is anSo, again, it's absolutely normal to augmenting objects in ES,
providing good documentation of what have you augmented (and for whole
code in general).
If you still wanna to write this as a rule, please mentioned, that
it's not the rule, but *just your own suggestion and own meaning*,
meanwhile other people can choose different (good) way augmenting
object and write in OOP-style such as `string.capitalize()' instead of
long ugly `Ext.util.Format.capitalize(string)'. Especially in own
project.
abstraction using inheritance, but it lacks encapsulation and modularity.
What exactly do you mean? Please explain.
Modifying the public interface of String changes Strings to be something different. Any code that uses String now has that change.
Creating a separate file for string utils does not impose a global change dependency.
Putting the captilize function in a separate separates the concern so that only as many modules as necessary depend on that module.
This minimizes dependencies, which makes code change possible. The less dependency you have, the easier it is to change.
There is no room for confusion in the intended interface with other modules.
Modifying built-ins prototypes maximizes the dependency. Everything has String.prototype, right? Well, now if you modify that, then everything has that modification.
Instead, the code should be doing the opposite; instead of maximizing scope, it should be minimizing scope. That way, when somebody wants to change it, he can. And (bonus) if he did a good job at minimizing dependency, it's easy (and he doesen't have to retest the entire system).
It is more like a reverse-inheritance type of scheme that changes String
in a way that may or may not be forwards-compatible. Object.create, for
a coincidental example, is now a built-in method, but exists as a
user-defined method in some codebases.
Util is not a descriptive package name.I do not agree that util is a good name for a package. Packages or unitsThat's not mine, that's real example from ExtJS library. I mentioned
of code should be organized by usage pattern.
"util" is a kitchen sink.
that to show how the code can converts into the overloaded massive
long lines using everywhere things such as procedure-like style
`Ext.util.Format.capitalize(string)'. Yeah, influence of Java is
conclusive in ExtJS library ;)
Not for Java, and not for Ext.js.
Take a look at java.util and please tell me Date have to do with Arrays
or TimerTask? Nothing, right?
Well javascript borrowed from Java, too. We've got the poor Date class
and Math. Many of the Math properties could have been moved to Number
and/or Number.prototype, depending on the property. Math.floor could be
Number.prototype.floor(), We could have 3.45.round() instead of
Math.round(3.45). Number.PI, Number.max(10, 11, 12). Well that is all
fiction made up but for me it makes way more sense than having a
separated Math class.
Yeah, it could easily be `3.45.round()' instead of `Math' I agree.
It seems worth considering changing that to Ext.string, and adding the
capitalize method to it.
Ext.string.capitalize("foo");
Collisions to that would be deliberate and you would know right off what
the capitalize method is, where it is defined, and not have to worry who
buggered String.prototype or if the buggering was a dual- action effort
on part of multiple third party libraries.
But there's no difference, will somebody put `capitalize' into the
`String.prototype' or will define own `Ext' or `Ext.string' namespace
- tomorrow, it can easily appear in all other libraries and in ES
itself. So, don't use name collision as a reason.
Moreover, I tell, people which use libraries think vice versa - they
think: "we don't not modify String.prototype as we're using 3rd-party
frameword, which can put tomorrow (in the next version) `capitalize'
method into it. So let's make our own namespace such as
OutSuperDuperNamespace.string and put `capitalize' there." And
tomorrow, OMG, that framework provides the same
`OutSuperDuperNamespace' and even `OutSuperDuperNamespace.string'
breaking down all the project. So, that's not the reason.
First off, who creates a namespace like "OutSuperDuperNamespace". Then, of those people, who then goes on to include *another* library that also the same (fruity) namespace?
A sensible developer would organize the coe into modules. Obviously "DOM" (in any case) would be likely to conflict on global level. I use, for example, APE.dom.
And that way, there is no need to worr about a getPosition or getCoords, or getStyle function. I have the DOM module, which is all about the dom, then within that there are modules for style, position, events, and each aspect is organized so that it is pretty narrow, small and easy to test.
That is modularity.
The capitalize method would not localize consistently, as noted recently
on ES-Discuss[1]. If the string is translated and included literally,
this doesn't occur.
I understand, but that's completely another question, and doesn't
touch the discussing topic.
In ES5, a property can be defined has having [[Writable]] = false.
This can happen in Object.create, with Object.defineProperty, setting
writable: false.
Object.freeze seals an object and makes its properties unmodifiable by
setting [[Writable]] to false.
Creating a sealed object eliminates the possibility for conflicts with
another Ext.string.capitalize.
Yep, thanks, I've also read ES-5 spec already. So, you're moving to
the way I told - better to suggest to use some static language in such
case, but not the language with dynamic mutable objects and statement
as a rule: "Do not touch your own objects".
"Do not touch your own objects" sounds like the exact opposite of what I meant.
So, if you'll write something like: "Remember that augmenting built-
ins may cause naming conflicts, bla-bla... but the same can be with
any other name in the program - no matter where it's - in global or in
own namespace" - that's will be normal. It will sound like suggesting
from your own opinion.
It's more than conflicts. Conflicts cause errors, but rigid APIs with a lot of interdependency make change hard.
But if you'll write - "Augmenting built-ins - is a bad practice" -
that will be categorical and wrong, and I can statement, that person
which spread that not completely understand the goal of dynamic
languages (I do not mean exactly you, I'm telling abstractly now).
I'm not completely sure what that means.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
.
- Follow-Ups:
- Re: Code Guidelines
- From: Dmitry A. Soshnikov
- Re: Code Guidelines
- References:
- Code Guidelines
- From: Garrett Smith
- Re: Code Guidelines
- From: Dr J R Stockton
- Re: Code Guidelines
- From: Garrett Smith
- Re: Code Guidelines
- From: Dmitry A. Soshnikov
- Re: Code Guidelines
- From: Garrett Smith
- Re: Code Guidelines
- From: Dmitry A. Soshnikov
- Re: Code Guidelines
- From: Garrett Smith
- Re: Code Guidelines
- From: Dmitry A. Soshnikov
- Code Guidelines
- Prev by Date: Re: Best Performance Javascript on IE6 for finding top and left using offsetTop and offsetLeft
- Next by Date: Re: Why won't my (j)query work?
- Previous by thread: Re: Code Guidelines
- Next by thread: Re: Code Guidelines
- Index(es):
Relevant Pages
|