Can't print 0 as an int, has to be a string (and only 0) #181

Closed
OscarGodson opened this Issue Aug 31, 2012 · 11 comments

Projects

None yet

4 participants

@OscarGodson
Contributor

For example:

<%
  // count == 3 in this example
  var i = 0;
  while(i <= count) {
%>
  <%= i %>
<%
    i++;
  }
%>

Will output:

1 2 3

However, if I change <%= i %> to <%= i.toString() %> it correctly outputs:

0 1 2 3
@polotek
Contributor
polotek commented Aug 31, 2012

Nice. This is because ejs runs the <%= val %> values through utils.string.escapeXML. And that expects a string to be passed and uses a falsey check. See the following.

https://github.com/mde/utilities/blob/master/lib/string.js#L50

This should probably do a check for undefined, null and NaN only. Anything else is valid output.

@larzconwell
Contributor

I changed the utils.string.escapeXML function so it just returns a function that consoles the input and then returns it. But it doesn't seem to get called at all?

@polotek
Contributor
polotek commented Aug 31, 2012

Well ejs does some evaling and such. May not be that simple. Also I didn't run any tests so I could be mistaken.

Sent from my iPhone

On Aug 31, 2012, at 11:38 AM, Larz Conwell notifications@github.com wrote:

I changed the utils.string.escapeXML function so it just returns a function that consoles the input and then returns it. But it doesn't seem to get called at all?


Reply to this email directly or view it on GitHub.

@larzconwell
Contributor

Yes, I'm looking at the EJS code right now.

It's calling a function that includes escapeXML, so AFAIK it should log when it's called but for some reason it isn't.

Edit: Apparently I'm a dumbass, my test was requiring a global(or local to Geddy) utilities install. Which I didn't update, oops.

@larzconwell larzconwell added a commit to mde/utilities that referenced this issue Aug 31, 2012
@larzconwell larzconwell Fixed cross issue from Geddy geddy/geddy#181 where EJS was calling st…
…ring.escapeXML which incorrectly replaced falsey values including 0(Number) with an empty string.

utils.escapeXML now only provides an empty string if the input is NaN, null or undefined.
048203a
@larzconwell
Contributor

Okay I this has been resolved in mde/utilities@048203a . Need to write more tests for utils.string.

@larzconwell
Contributor

@polotek What's a good way to check for NaN? isNaN isn't the best thing to do..

@polotek
Contributor
polotek commented Aug 31, 2012

There are very stick conversion rules for isNaN. Essentially any truthy
value you want to just let pass. We're really only trying to differentiate
falsy values. NaN itself is falsy, but it also has some weird behavior with
other falsey values. e.g. isNaN(null) === false but isNaN(undefined) ===
true. Most of the time it's best to just leave it out.
But occasionally it's important to account. Cases like this where 0 is
valid value so you can't count on normal conversion. And because it
"infects" other operations. Once you have NaN in any numerical operations,
it results in a NaN outcome.

Anyway, long story short, you want to check for all other falsey values you
care about. And then check for isNaN as the last resort.

if(val === null || val === undefined || (!val && isNaN(val)) { val = ''; }

Notice that we check for null and undefined first, because they have
different behavior in isNaN. Then we also check the falseyness of the val.
Because any positive value that is NOT and actual number behaves oddly for
isNaN. But the number 0 will always say false. So essentially the value is
not null and not undefined, but it is falsey, there are only a few values
left that it could be: NaN, 0, or '"" (empty string). We want to pass
through 0 and empty string, and not pass through NaN. And that works here.

> isNaN(0)
false
> isNaN('')
false
> isNaN(NaN)
true

You can throw a bunch of test values at this to make sure it's what we want.

:Marco

On Fri, Aug 31, 2012 at 12:46 PM, Larz Conwell notifications@github.comwrote:

@polotek https://github.com/polotek What's a good way to check for NaN?
isNaN is returning true if the argument is a String, Object or Number..


Reply to this email directly or view it on GitHubhttps://github.com/mde/geddy/issues/181#issuecomment-8203014.

Marco Rogers
marco.rogers@gmail.com | https://twitter.com/polotek

Life is ten percent what happens to you and ninety percent how you respond
to it.

  • Lou Holtz
@mde
Contributor
mde commented Aug 31, 2012

Nicely said. :)

@larzconwell
Contributor

Thanks for the explanation @polotek ! That explains why it was being so odd with input.

@mde
Contributor
mde commented Aug 31, 2012

Oh, might be worth mentioning, another reason for isNaN is because NaN isn't equal to anything -- even itself:

> (NaN == NaN);
false
@larzconwell
Contributor

Yep reading MDN article on it now (:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment