On Feb 10, 9:35 pm, Jim Higson <j...@333.org> wrote:
> On Feb 8, 1:19 pm, RobG <rg...@iinet.net.au> wrote:
[...]
> > It's a bit unfair to blame the language for what you consider an
> > inappropriate use of one of its features.  Perhaps the name of the
> > function should be "isStringPrimitive".
>
> I guess I *am* blaming Javascript for having (in effect) two string
> types. No other languages do this and (as far as I know) having two
> kinds of strings doesn't let you do any cool stuff that you couldn't
> do with one.

I'm not arguing that javascript (or more correctly here ECMA-262, but
javascript will do) is perfect, I'm just accepting it at face value.
It was designed to be a simple, easy to use language so a primitive
string will act as a string object when it needs to in most cases.


> I see having two string types as one of those strange quirks of
> Javascript that libraries like Prototype should smooth over so the
> programmer can just think "...Ok I've got a string..." without
> worrying which of the types of strings s/he has.

What is needed is an appropriate test in the right place, what you
really want to test is "is this thing suitable for what I am about to
do with it".

There are many cases where you can pass a string or number primitve
and not care which one you have, but if your parameter accepts either
object or primitive and you discriminate using typeof (masked by a
wrapper function), anything that passes a String or Number may cause
it to do inappropriate things.


[...]
> > It is extremely rare to come across a String object in javascript, so
> > there seems very little point in an isString function when the vast
> > majority of the time a typeof test is sufficient (and less
> > problematic).
>
> Personally, I think the rareness of String objects is part of the
> reason why it *is* desirable to take them into the account. As a
> programmer you make assumptions that you're dealing with normal
> strings, then suddenly an object String turns up everything breaks.
> But you come to debug and the object string looks a lot like a normal
> string and the bug takes ages to track down.

Your interface should be documented and say what type arguments must
be.  You can't test every input always to see what you have (Number,
Math, RegExp and a variety of host objects will 'object') you have to
make some assumptions about the competence of whoever is using your
API.  At least if it is failing on typeof it should not get to
production (unless testing is deficient too, or the behaviour is seen
as a feature...).


> I started this thread when some library code I use started acting
> oddly.
> It turns out this was because some other code (which I didn't write)
> was passing new String('foo') into it.
>
> Off the top of my head, my code was something like:
>
> if( Object.isString( foo ) ){
>    do something( foo );}else if( Object.isObject( foo ) ){
>
>    foo.each( function( i ){ /* ... */ } )
>
> }
>
> So given a String object was iterating through each char in the
> String.

Cool!  See, extra features the client didn't expect!  :-)


> > In the unlikely event that you want to know if the thing you have is a
> > String object, use instanceof.  What is the use of an isString
> > function that can't tell the difference between an object and a
> > primitive?
>
> I think treating them as both just Strings makes for easier to read
> code.

The language is designed so you shouldn't need to care.  I think this
helps the argument of why functions like isString are not a good
idea.  If you want to test for specific properties or features of an
object, test for them.  Don't test some other property and make
assumptions based on it, which is what isString encourages.

Much better to learn the ins and outs of typeof and other operators so
you know to use them appropriately.  It doesn't make sense to me to
paper over such things as they will come back to haunt you in
unexpected ways.


> At the moment I test like this:
>
> if( Object.isString( foo ) ||
>   ( Object.isObject( foo ) && foo.constructor == String ) ) {
> //...
> }
>
> I can't think of any reason why I'd want to react to primitive Strings
> differently from string objects, so I think just writing this makes
> clearer code:
>
> if( Object.isString( foo ) ) {
> //...

But that is your concept of a string, others may differ.   I'm not
going to defend functions like isString etc. since I disagree with the
concept behind them for a language like javascript where the concept
of "isSomething" is not well defined on purpose (again, I'm not saying
that is good or bad, it's just the way it is).


> }
> > I can't conceive of a scenario where a String object would be used and
> > I'd get into a situation where I needed to test for something that was
> > either an object or a string.  If it doesn't matter, why use an
> > object?
>
> Because I can't always control the values that are passed to functions
> that I write. I don't know of any good reason why one would create a
> String object, but if some client code does I should at least handle
> it gracefully.

Your issue was more to do with making an assumption that if the
variable wasn't a string, it was a suitable object.  Not an obvious
error, but one that 20/20 hindsight should prevent from occuring
again.


> > And if it did matter, I'd want to test for one or the other
> > in which case neither the current isString or your suggested
> > modification would do the job.
>
> Can you give examples of where it would matter?

No, so I can't justify an isString function.

> > Perhaps is should return one of three values: primitive, object or
> > boolean false.  Then if you don't care, you can use use:
>
> >   if (isString(...)) ...
>
> > as either 'object' or 'primitive' will resolve to true, but boolean
> > false will be false.
>
> > If you do care, you can use:
>
> >   if (isString(...) ==  'primitive') ...
>
> I think this is a very neat solution :-)

I was joking... :-)

[...]
> > It can hardly be called a bug when it does what the documentation says
> > it does (I think "works as designed" is the polite response).  The
> > function itself is a bit pointless though, as are similar functions
> > like isNumber, e.g.
>
> Ok, but it can "work as designed" and the design can be sub-optimal.

Yes, it might be a bug in the design, but there are no requirements
(other than yours posted above) on which to judge the design.

Incidentally, Prototype.js uses isString in 12 places, so your
suggested mod has some consequences.


--
Rob
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to