[Proto-Scripty] Re: Prototype bug?

2009-02-11 Thread Jim Higson

On Wednesday 11 February 2009 05:06:55 RobG wrote:
 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.

With Strings, It is probably *always* the correct way to look at the 
constructor, ie if( foo.constructor == String ) - this tells me if it is a 
string (obejct or literal) without me having to care how the string was 
created.

I can't think of any time when I care if it is an object or literal, so IMO 
for strings looking at the constructor is *just*better* than asking typeof. If 
we're going to have isString at all it might as well check using the more 
useful constructor way rather than the less useful typeof way.

 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.

I think Object.isString(s) as a replacement for (s.constructor == String) 
makes the code a little easier to read, especially when used alongside other 
type checks. For example, I might have:

if( Object.isString( foo ) ) {
/* ... */
}elseif( Object.isObject( foo ) ){
/* ... */
}

which (I think) is nicer than this:

if( foo.constructor == String ) {
/* ... */
}elseif( typeof foo == 'object' ){
/* ... */
}

Of course this is purely subjective but I find the repetition makes it more 
obvious at first glance that we're checking for type both times.

[snip]

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

Then presumably 12 of places in Prototype don't think String objects exist and 
would break if passed them. I've never seen the API specify literal strings so 
here's the bug :-)

If it has been fixed in trunc (I haven't checked, but it was said to have been 
in this thread), presumably the 12 places didn't cause regressions.

-- 
Jim
blog: http://jimhigson.blogspot.com/
web: http://wikizzle.org

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Prototype bug?

2009-02-10 Thread Jim Higson

On Feb 8, 1:19 pm, RobG rg...@iinet.net.au wrote:
 On Feb 8, 12:55 am, Jim Higson j...@333.org wrote:

  alert( Object.isString( foo ));
  // alerts string

 It alerts true.

So it does ^-)

  alert( Object.isString( new String( foo ) ));
  // alerts object

 It alerts false.

^-) again

  I know why this happens - because Prototype uses the underlying typeof's
  understanding of type.

 That typeof returns the type is pretty reasonable given that it is
 called typeof.


  Personally I think this is a bug though - Javascript is just being difficult
  here

 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 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.

  and Prototype should make stuff like this easier. It should
  return string regardless of how the string was created.

 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.

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.

 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.

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 ) ) {
//...
}

 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.

 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?

 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 :-)

 The bottom line is to look at why you would use such a function, and
 whether there are already suitable language features that do the job.

  Anyone agree I should file this as a bug, or is there a good reason the
  current behaviour is desirable?

 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.

--
Jim
blog: http://jimhigson.blogspot.com/
web: http://wikizzle.org
--~--~-~--~~~---~--~~
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 

[Proto-Scripty] Re: Prototype bug?

2009-02-10 Thread Richard Quadling

2009/2/10 Jim Higson j...@333.org:

 On Feb 8, 1:19 pm, RobG rg...@iinet.net.au wrote:
 On Feb 8, 12:55 am, Jim Higson j...@333.org wrote:

  alert( Object.isString( foo ));
  // alerts string

 It alerts true.

 So it does ^-)

  alert( Object.isString( new String( foo ) ));
  // alerts object

 It alerts false.

 ^-) again

  I know why this happens - because Prototype uses the underlying typeof's
  understanding of type.

 That typeof returns the type is pretty reasonable given that it is
 called typeof.


  Personally I think this is a bug though - Javascript is just being 
  difficult
  here

 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 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.

  and Prototype should make stuff like this easier. It should
  return string regardless of how the string was created.

 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.

 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.

 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.

 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 ) ) {
 //...
 }

 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.

 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?

 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 :-)

 The bottom line is to look at why you would use such a function, and
 whether there are already suitable language features that do the job.

  Anyone agree I should file this as a bug, or is there a good reason the
  current behaviour is desirable?

 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.

 --
 Jim
 blog: http://jimhigson.blogspot.com/
 web: http://wikizzle.org
 


Ha. I'm relatively new to JS and I though that ...

var s_String = bob;

was just a shortcut for

var s_LooksLikeAStringButDoesNotGoQuack = new String(bob);

I always thought that internally they were the same thing.

It seems truely strange that they are not. If that is indeed the case.

Yet I can call 

[Proto-Scripty] Re: Prototype bug?

2009-02-10 Thread Jim Higson


 Ha. I'm relatively new to JS and I though that ...

 var s_String = bob;

 was just a shortcut for

 var s_LooksLikeAStringButDoesNotGoQuack = new String(bob);

 I always thought that internally they were the same thing.

I think a lot of people who used Javascript for a long time think the
same. Most languages they would be.

 It seems truely strange that they are not. If that is indeed the case.

 Yet I can call string methods on s_String just like I can on
 s_LooksLikeAStringButDoesNotGoQuack though.

  s_String = 'bob';
 bob
  s_String.toUpperCase()
 BOB
  o_String = new String('bob')
 bob
  o_String.toUpperCase()
 BOB
  typeof o_String
 object
  typeof s_String

 string

 There is a difference shown in FireBug in that o_String allows a
 breakdown of ...

 0   b
 1   o
 2   b

 What does new String(bob) offer over normal bob?

As far as I know, nothing. Hence my assertion that Prototype should
treat object strings as if they were a normal string.

The Moz docs say in a few places things like:

You should use string literals unless you specifically need to use a
String object, because String objects can have counterintuitive
behavior.
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Predefined_Core_Objects/String_Object

But they don't give an example of this specific need. I dunno why
someone would call new String(), but if they *do* create strings that
way, IMO Javascript library code should treat them like native
strings.

--
Jim
blog:http://jimhigson.blogspot.com/
web:http://wikizzle.org
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Prototype bug?

2009-02-10 Thread Richard Quadling

2009/2/10 Jim Higson j...@333.org:


 Ha. I'm relatively new to JS and I though that ...

 var s_String = bob;

 was just a shortcut for

 var s_LooksLikeAStringButDoesNotGoQuack = new String(bob);

 I always thought that internally they were the same thing.

 I think a lot of people who used Javascript for a long time think the
 same. Most languages they would be.

 It seems truely strange that they are not. If that is indeed the case.

 Yet I can call string methods on s_String just like I can on
 s_LooksLikeAStringButDoesNotGoQuack though.

  s_String = 'bob';
 bob
  s_String.toUpperCase()
 BOB
  o_String = new String('bob')
 bob
  o_String.toUpperCase()
 BOB
  typeof o_String
 object
  typeof s_String

 string

 There is a difference shown in FireBug in that o_String allows a
 breakdown of ...

 0   b
 1   o
 2   b

 What does new String(bob) offer over normal bob?

 As far as I know, nothing. Hence my assertion that Prototype should
 treat object strings as if they were a normal string.

 The Moz docs say in a few places things like:

 You should use string literals unless you specifically need to use a
 String object, because String objects can have counterintuitive
 behavior.
 https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Predefined_Core_Objects/String_Object

 But they don't give an example of this specific need. I dunno why
 someone would call new String(), but if they *do* create strings that
 way, IMO Javascript library code should treat them like native
 strings.

 --
 Jim
 blog:http://jimhigson.blogspot.com/
 web:http://wikizzle.org
 


So, it seems the only place where things go wonky is with eval().

And the odd behaviour indicates that the toString() method isn't
called on a string object when using eval(). More wierd.

 s1 = 2 + 2
2 + 2
 s2 = new String(3 + 3)
3 + 3
 eval(s1)
4
 eval(s2)
3 + 3
 eval(s2.toString())
6

This is just odd behaviour, but having read the MDC, it does explain
what happens internally when String methods are called in a text
string.

I wonder if the same sort of issues apply to

i_Seven = 7;

vs

o_Seven = new Number(7);

 i_Seven = 7
7
 o_Seven = new Number(7)
7
 typeof i_Seven
number
 typeof o_Seven
object

and boolean

 b_True = true
true
 o_True = new Boolean(true)
true
 typeof b_True
boolean
 typeof o_True
object

There are no additional properties on a Number or Boolean objects as
far as FireBug is reporting.

So, with boolean/string/number accessible as primitives AND objects,
then instanceof seems to be the way to identify things.

 o_String = new String(stringy string)
stringy string 0=s 1=t 2=r 3=i 4=n 5=g 6=y 7= 8=s 9=t 10=r 11=i 12=n 13=g
 s_String = string string
string string
 typeof o_String
object
 typeof s_String
string
 o_String instanceof String
true
 s_String instanceof String
false

Confusing.
-- 
-
Richard Quadling
Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498r=213474731
Standing on the shoulders of some very clever giants!

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Prototype bug?

2009-02-10 Thread Jim Higson

  What does new String(bob) offer over normal bob?

 As far as I know, nothing. Hence my assertion that Prototype should
 treat object strings as if they were a normal string.

Hmmm... actually I should have said nothing I've ever found
useful :-)

With strings-that-look-like-strings-but-are-really-objects because
they are objects you can add properties and things to them.

For example this works:

var obstr = new String(foo);
foo.titlecase = function (){ /* ... */ };

but not this:

var str = foo;
foo.titlecase = function (){ /* ... */ };

But, personally, I think this is confusing the definition of strings
and you're better off either adding to String.prototype (which will
make the method usable for all strings of both types) or just
providing a titlecase function that takes a string as an argument.

--
Jim
blog:http://jimhigson.blogspot.com/
web:http://wikizzle.org
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Prototype bug?

2009-02-10 Thread Richard Quadling

2009/2/10 Jim Higson j...@333.org:

  What does new String(bob) offer over normal bob?

 As far as I know, nothing. Hence my assertion that Prototype should
 treat object strings as if they were a normal string.

 Hmmm... actually I should have said nothing I've ever found
 useful :-)

 With strings-that-look-like-strings-but-are-really-objects because
 they are objects you can add properties and things to them.

 For example this works:

 var obstr = new String(foo);
 foo.titlecase = function (){ /* ... */ };

 but not this:

 var str = foo;
 foo.titlecase = function (){ /* ... */ };

 But, personally, I think this is confusing the definition of strings
 and you're better off either adding to String.prototype (which will
 make the method usable for all strings of both types) or just
 providing a titlecase function that takes a string as an argument.

 --
 Jim
 blog:http://jimhigson.blogspot.com/
 web:http://wikizzle.org
 


 var s_String = foo
 s_String
foo
 s_String.titlecase = function(){return substring(this,1,1).toUpperCase() + 
 substring(this,2);}
function()

So, you CAN add it. I suspect it is an internal object is created and
then dropped.

Completely useless.


-- 
-
Richard Quadling
Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498r=213474731
Standing on the shoulders of some very clever giants!

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Prototype bug?

2009-02-10 Thread kangax

On Feb 10, 10:05 am, Richard Quadling rquadl...@googlemail.com
wrote:
[...]
 So, it seems the only place where things go wonky is with eval().

`eval ` treats passed string as a Program, and evaluates it as such.
There's nothing wonky about it : )


 And the odd behaviour indicates that the toString() method isn't
 called on a string object when using eval(). More wierd.

  s1 = 2 + 2
 2 + 2

String literal (primitive) is created.

  s2 = new String(3 + 3)
 3 + 3

String object (with the internal [[Value]] set to 3 + 3) is created.

  eval(s1)
 4

2 + 2 string primitive is evaluated as a Program and the result of
its production is returned - `4`

  eval(s2)
 3 + 3

`eval` does *NOT* do anything when you pass it a non-string value
(which you do in this case - as `s2` is an Object, not a string). It
simply returns what was given (which is an object with a value of 3 +
3)

  eval(s2.toString())

 6

Here, you take that String object and call its `toString` method.
`toString` returns whatever is stored in String object's internal
[[Value]] - that is 3 + 3. The returned 3 + 3 is a string
primitive and so `eval` rightfully evaluates it, returning `6`

Read ECMA specs URL http://bclary.com/2004/11/07/  if you really
want to know what's going on under the hood (or even to be able to
explain/understand simple examples like the above). You'll be
surprised how clear everything becomes once you do ; )

--
kangax
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Prototype bug?

2009-02-10 Thread RobG



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 

[Proto-Scripty] Re: Prototype bug?

2009-02-08 Thread RobG



On Feb 8, 12:55 am, Jim Higson j...@333.org wrote:
 alert( Object.isString( foo ));
 // alerts string

It alerts true.

 alert( Object.isString( new String( foo ) ));
 // alerts object

It alerts false.


 I know why this happens - because Prototype uses the underlying typeof's
 understanding of type.

That typeof returns the type is pretty reasonable given that it is
called typeof.


 Personally I think this is a bug though - Javascript is just being difficult
 here

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.

 and Prototype should make stuff like this easier. It should
 return string regardless of how the string was created.

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).

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 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?  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.

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') ...

The bottom line is to look at why you would use such a function, and
whether there are already suitable language features that do the job.

 Anyone agree I should file this as a bug, or is there a good reason the
 current behaviour is desirable?

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.

  Object.isNumber(NaN); // true

Consider:

  var x = 'a' * 2;
  Object.isNumber(x) );  // true


--
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Prototype bug?

2009-02-08 Thread kangax

On Feb 8, 8:19 am, RobG rg...@iinet.net.au wrote:
[...]
 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.

It's not pointless, but the scope of its use is indeed pretty narrow.
Since neither `instanceof` operator nor `constructor` value check can
not be relied upon when working with multiple contexts (frames),
`Object.isString` is here to take care of it. AFAIK, ES committee is
planning to finally document ECMA behavior in context of multiple
global objects.


   Object.isNumber(NaN); // true

Should it return `false`?

4.3.23 (NaN) says that ... This value is a member of the Number
type.. Also, `typeof NaN == number`, NaN's `constructor` is
`Number`, its [[Class]] is Number and it's [[Prototype]] references
`Number.prototype`? Should we return `false` for practical reasons?

And what should `Object.isNumber` return for +/-Inifinity? Adding
`isFinite` to `isNumber` would be able to take care of both - `NaN`
and `Infinity` cases.

--
kangax
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Prototype bug?

2009-02-08 Thread RobG

On Feb 8, 11:53 pm, kangax kan...@gmail.com wrote:
 On Feb 8, 8:19 am, RobG rg...@iinet.net.au wrote:
 [...]

  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.

 It's not pointless, but the scope of its use is indeed pretty narrow.

Can you provide a scenario where isNumber is more suitable than
typeof?  If not the scope of its usefulness is zero.

 Since neither `instanceof` operator nor `constructor` value check can
 not be relied upon when working with multiple contexts (frames),
 `Object.isString` is here to take care of it.

They test for completely different things.  I would guess that if
instanceof or constructor tests are necessary, typeof is unlikely to
be a useful replacement regardless of the context.  If typeof is a
suitable replacement, then there was no point in using instanceof et
al in the first place.

Can you write an isNumber function that uses instanceof across frames
successfully?  And if so, can you define the time when such
functionality would be useful?


 AFAIK, ES committee is
 planning to finally document ECMA behavior in context of multiple
 global objects.

Great, but irrelevant to the current discussion.  Or are you inferring
that isNumber is simply a placeholder for possibly useful (but as yet
undefined) future functionality?


Object.isNumber(NaN); // true

 Should it return `false`?

According to the documentation, no - but the function name suggests
otherwise.  Perhaps ‘isNumberType’ more accurately reflects what the
function does.

Anyway, it doesn't matter what I think it should return - ask those
who are its intended user base.  Should isNumber('5') return true?
The documentation says isNumber is a wrapper for typeof, so why not
just use typeof and save the confusion?


 4.3.23 (NaN) says that ... This value is a member of the Number
 type.. Also, `typeof NaN == number`, NaN's `constructor` is
 `Number`, its [[Class]] is Number and it's [[Prototype]] references
 `Number.prototype`? Should we return `false` for practical reasons?

You're making my argument for me.   :-)

All those points are valid and highlight that if one or more of those
properties are of interest, they should be tested for explicitly.
There are values that aren't numbers (either Objects or primitives)
that can be used safely in arithmetic operations and some that are
numbers that can't.

A function like isNumber can't cover all possibilities unless it
returns a variety of values depending on the type, constructor, etc.
and if it was one of those properties that are really of interest, why
not test for it directly?


 And what should `Object.isNumber` return for +/-Inifinity? Adding
 `isFinite` to `isNumber` would be able to take care of both - `NaN`
 and `Infinity` cases.

If the current behaviour is not suitable (it seems to do exactly what
it is documented to do, so I’m not complaining about that), then the
first step in writing a new isNumber function is to define its purpose
- what is it for?  Next would be to define what a number is (which may
seem trivial at first glance but the points discussed above show it
isn't) and the context in which isNumber is or isn’t suitable.  Is it
to test that the value is type number? An instance of Number? A value
that can safely be used in an arithmetic operation? One that can be
converted to a useful number? And so on.

Without knowing what the purpose of the function is, it’s impossible
to say how it should handle edge cases.   And if a purpose can’t be
stated concisely, then perhaps it doesn’t have one that is useful.


--
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Prototype bug?

2009-02-08 Thread RobG



On Feb 9, 11:37 am, kangax kan...@gmail.com wrote:
 On Feb 8, 7:32 pm, RobG rg...@iinet.net.au wrote:

  On Feb 8, 11:53 pm, kangax kan...@gmail.com wrote:
 [...]
   It's not pointless, but the scope of its use is indeed pretty narrow.

  Can you provide a scenario where isNumber is more suitable than
  typeof?  If not the scope of its usefulness is zero.

 Of course. `isNumber` (as it is in a trunk) will return `true` for
 Number *object*, while `typeof` will obviously return object.
 Whether Number objects are something that should be present in a
 script (rather than simple number primitives) is a different topic.

Not at all, it's what I was asking for.  I can't conceive of a
situation where I would use isNumber (either in its current state or
the proposed modification).  I'm asking for a scenario where I would
*use* it.

[...]

   AFAIK, ES committee is
   planning to finally document ECMA behavior in context of multiple
   global objects.

  Great, but irrelevant to the current discussion.  Or are you inferring
  that isNumber is simply a placeholder for possibly useful (but as yet
  undefined) future functionality?

 `isNumber` is an abstraction level. A noble (but ill-conceived) goal
 to unify type checking in diverse Javascript land : ) IIRC, the first
 version of `isNumber` looked like - `return typeof object ==
 number`, and was added for *consistency* with other `Object.is*`
 methods - an infamous `isArray` was one of the first ones (following
 by others). Right now, I don't believe in generic solutions. The best
 way to go is to get familiar with language and use whatever fits the
 best. Nevertheless, checking for [[Class]] == Number seems to cover
 most of what masses desire (I'm also inclined to making `isNumber`
 filter out `NaN` and `Infinity`)

Now you are back on topic.  But [[Class]] can only be indirectly read
via toString, so it isn't that reliable but might be good enough for
most.  Anything that has a [[Class]] of Number should probably emulate
the properties of a native Number.  The argument now goes to the same
place as isArray - no need to repeat that here.  :-)


  Object.isNumber(NaN); // true

   Should it return `false`?

  According to the documentation, no - but the function name suggests

 I'm not talking about documentation at this point. I'm interested in
 your opinion (but you already said it best few paragraphs down)

  otherwise.  Perhaps ‘isNumberType’ more accurately reflects what the
  function does.

 Well, the way it's implemented at the moment is by checking object's
 [[Class]]. If anything, it should be called isNumberClass but then
 there's possibility of a confusion with Class in its common OOP
 sense.

And Prototype.js's implementation of Class also.  What a tangled web
we weave. :-)


  Anyway, it doesn't matter what I think it should return - ask those
  who are its intended user base.  Should isNumber('5') return true?
  The documentation says isNumber is a wrapper for typeof, so why not
  just use typeof and save the confusion?

 I'd rather change documentation, since as we know by now, `typeof` is
 not always sufficient (and whenever it is - it can just be used
 explicitly, without resorting to any higher order helpers).

Given that in version 1.6.0.3 (the current version as far as I know)
it is:

  isNumber: function(object) {
return typeof object == number;
  },

the documentation is correct.  Perhaps you meant change the
documentation when the new version is published.



   4.3.23 (NaN) says that ... This value is a member of the Number
   type.. Also, `typeof NaN == number`, NaN's `constructor` is
   `Number`, its [[Class]] is Number and it's [[Prototype]] references
   `Number.prototype`? Should we return `false` for practical reasons?

  You're making my argument for me.   :-)

  All those points are valid and highlight that if one or more of those
  properties are of interest, they should be tested for explicitly.
  There are values that aren't numbers (either Objects or primitives)
  that can be used safely in arithmetic operations and some that are
  numbers that can't.

  A function like isNumber can't cover all possibilities unless it
  returns a variety of values depending on the type, constructor, etc.
  and if it was one of those properties that are really of interest, why
  not test for it directly?

 Yes. Using the right tool for the job was the morale of my first post
 in this thread - Javascript is actually quite flexible... : )


   And what should `Object.isNumber` return for +/-Inifinity? Adding
   `isFinite` to `isNumber` would be able to take care of both - `NaN`
   and `Infinity` cases.

  If the current behaviour is not suitable (it seems to do exactly what
  it is documented to do, so I’m not complaining about that), then the
  first step in writing a new isNumber function is to define its purpose
  - what is it for?  Next would be to define what a number is (which may
  seem trivial at first glance but the points 

[Proto-Scripty] Re: Prototype bug?

2009-02-08 Thread kangax

On Feb 8, 9:59 pm, RobG rg...@iinet.net.au wrote:
 On Feb 9, 11:37 am, kangax kan...@gmail.com wrote:

[...]

  Of course. `isNumber` (as it is in a trunk) will return `true` for
  Number *object*, while `typeof` will obviously return object.
  Whether Number objects are something that should be present in a
  script (rather than simple number primitives) is a different topic.

 Not at all, it's what I was asking for.  I can't conceive of a
 situation where I would use isNumber (either in its current state or
 the proposed modification).  I'm asking for a scenario where I would
 *use* it.

I can't think of such scenario. I personally never use primitive
wrappers explicitly (language does a pretty good job at wrapping
primitives for me :))

[...]

  `isNumber` is an abstraction level. A noble (but ill-conceived) goal
  to unify type checking in diverse Javascript land : ) IIRC, the first
  version of `isNumber` looked like - `return typeof object ==
  number`, and was added for *consistency* with other `Object.is*`
  methods - an infamous `isArray` was one of the first ones (following
  by others). Right now, I don't believe in generic solutions. The best
  way to go is to get familiar with language and use whatever fits the
  best. Nevertheless, checking for [[Class]] == Number seems to cover
  most of what masses desire (I'm also inclined to making `isNumber`
  filter out `NaN` and `Infinity`)

 Now you are back on topic.  But [[Class]] can only be indirectly read
 via toString, so it isn't that reliable but might be good enough for
 most.  Anything that has a [[Class]] of Number should probably emulate
 the properties of a native Number.  The argument now goes to the same
 place as isArray - no need to repeat that here.  :-)

Getting [[Class]] is actually very much reliable (and is clearly
documented in specs). I wrote a post about it some time ago [1]. The
only downside is host objects, which are obviously permitted to have
any [[Class]] value, including one of the native ones - Array,
Function, Number, etc. IIRC, ES commitee is currently discussing
this as well (Restrictions of [[Class]] values in context of host
objects).

[...]

 Given that in version 1.6.0.3 (the current version as far as I know)
 it is:

   isNumber: function(object) {
     return typeof object == number;
   },

 the documentation is correct.  Perhaps you meant change the
 documentation when the new version is published.

Yes, we need to change it once the next release (current trunk) comes
out.

[...]

[1] 
http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/

--
kangax
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Prototype bug?

2009-02-07 Thread Tobie Langel

That's been fixed in trunk.

Best,

Tobie

On Feb 7, 3:55 pm, Jim Higson j...@333.org wrote:
 alert( Object.isString( foo ));
 // alerts string
 alert( Object.isString( new String( foo ) ));
 // alerts object

 I know why this happens - because Prototype uses the underlying typeof's
 understanding of type.

 Personally I think this is a bug though - Javascript is just being difficult
 here and Prototype should make stuff like this easier. It should
 return string regardless of how the string was created.

 Anyone agree I should file this as a bug, or is there a good reason the
 current behaviour is desirable?

 Cheers,
 Jim

 --
 Jim Higson
 my blog:http://jimhigson.blogspot.com/
 wikizzle:http://wikizzle.org
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Prototype bug?

2009-02-07 Thread kangax

On Feb 7, 9:55 am, Jim Higson j...@333.org wrote:
 alert( Object.isString( foo ));
 // alerts string
 alert( Object.isString( new String( foo ) ));
 // alerts object

 I know why this happens - because Prototype uses the underlying typeof's
 understanding of type.

 Personally I think this is a bug though - Javascript is just being difficult
 here and Prototype should make stuff like this easier. It should
 return string regardless of how the string was created.

 Anyone agree I should file this as a bug, or is there a good reason the
 current behaviour is desirable?

Javascript is actually quite flexible in this regard. If you want to
check whether an object is a string *primitive* - use `typeof` and
compare result to string. If you want to know whether an object is
an instance of `String` function and inherits from `String.prototype`,
use `instanceof` operator or check object's `constructor` property. If
you need to use any of `String.prototype.*` methods, explicitly check
for a presence of those methods on an object (since property lookup
would propagate up the prototype chain) - e.g. `if (typeof
object.charCodeAt == 'function') { ... }`; Finally, you can always
check object's internal [[Class]] for a value of String (which all
*native* String *objects* have). In a trunk of prototype.js, we use
this last method - Object.prototype.toString.call(object) === '[object
String]', where `call` first converts a value to an object and
`Object.prototype.toString` then checks that object's [[Class]] value;
It works for both - primitives and their object representations.

--
kangax
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---