[Proto-Scripty] Re: Prototype bug?
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?
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/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?
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/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?
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/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?
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?
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?
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?
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?
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?
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?
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?
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?
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 -~--~~~~--~~--~--~---