On Wed, Aug 22, 2012 at 1:29 PM, Jimb Esser <wastel...@gmail.com> wrote:
> Yeah, there are a lot of cases where "does not exists" as an "error" needs
> to be treated differently. I tried making a "read from this file, return a
> default value if it does not exist" function without using fs.exists, and
> was unable to do so efficiently without relying on undocumented error code
> values [1]. It's very unclear if that code will work on different versions
> of node let alone different operating systems. It's vitally important in
> cases like "rename this file to a backup before overwriting" that an "error"
> in the process is treated differently than "file does not exists", so
> fs.exists does serve a purpose, even if its signature could have been
> designed in a more conformant manner.
Yeah, Jimb, I'm not sure I know what you mean by "undocumented error
code values". Node does assume some familiarity with Posix error code
values, but that's a very long and well-documented tradition.
Actually, your gist is a perfect example of why fs.exists is a)
unnecessary, and b) almost always the wrong idea. In the first case,
if the file exists, but is not readable, then the fs.exists() will
return false, and your program will act as if the file is *missing*,
which is incorrect.
On Wed, Aug 22, 2012 at 2:10 PM, Nathan Rajlich <nat...@tootallnate.net> wrote:
> Checking "err.code" for "ENOENT" is the most cross-platform and
> backwards compatible way to check for the existence of the file.
> On Wed, Aug 22, 2012 at 1:29 PM, Jimb Esser <wastel...@gmail.com> wrote:
>> Yeah, there are a lot of cases where "does not exists" as an "error" needs
>> to be treated differently. I tried making a "read from this file, return a
>> default value if it does not exist" function without using fs.exists, and
>> was unable to do so efficiently without relying on undocumented error code
>> values [1]. It's very unclear if that code will work on different versions
>> of node let alone different operating systems. It's vitally important in
>> cases like "rename this file to a backup before overwriting" that an "error"
>> in the process is treated differently than "file does not exists", so
>> fs.exists does serve a purpose, even if its signature could have been
>> designed in a more conformant manner.
I can find no reference in the Node documentation to "ENOENT" other than in regards to DNS functions, no description at all in the File System documentation on what the error objects are (other than examples using them as booleans or opaque types to be displayed or thrown), nothing even saying an "Error" type has a "code" member you can reliably do anything with. I would not call that "well-documented". Coming from Windows-land, having never seen "ENOENT" before, I just assumed that was an internal libuv identifier or something.
At least in any case I tested, if a file exists and is not readable, fs.exists returns "true", as I'd expect. There are probably some cases (perhaps if the file is in a location you do not have access to, as opposed to the fairly common case of just being unable to access a file) where the current fs.exists would return "false", but that's just a really good argument that the current fs.exists should only return false if stat returned an error *and* that error was "ENOENT" or whichever set of error codes indicates non-existence, not that the API is flawed. Abstracting away exactly which behaviors or error codes indicate "existence" is useful.
On Wednesday, August 22, 2012 2:32:43 PM UTC-7, Isaac Schlueter wrote:
> Yeah, Jimb, I'm not sure I know what you mean by "undocumented error > code values". Node does assume some familiarity with Posix error code > values, but that's a very long and well-documented tradition.
> Actually, your gist is a perfect example of why fs.exists is a) > unnecessary, and b) almost always the wrong idea. In the first case, > if the file exists, but is not readable, then the fs.exists() will > return false, and your program will act as if the file is *missing*, > which is incorrect.
> On Wed, Aug 22, 2012 at 2:10 PM, Nathan Rajlich <nat...@tootallnate.net<javascript:>> > wrote: > > Checking "err.code" for "ENOENT" is the most cross-platform and > > backwards compatible way to check for the existence of the file.
> > On Wed, Aug 22, 2012 at 1:29 PM, Jimb Esser <wast...@gmail.com<javascript:>> > wrote: > >> Yeah, there are a lot of cases where "does not exists" as an "error" > needs > >> to be treated differently. I tried making a "read from this file, > return a > >> default value if it does not exist" function without using fs.exists, > and > >> was unable to do so efficiently without relying on undocumented error > code > >> values [1]. It's very unclear if that code will work on different > versions > >> of node let alone different operating systems. It's vitally important > in > >> cases like "rename this file to a backup before overwriting" that an > "error" > >> in the process is treated differently than "file does not exists", so > >> fs.exists does serve a purpose, even if its signature could have been > >> designed in a more conformant manner.
Isaac, i am curious why you believe fs.exists should stay as is.
I found your previous mail kind of "autarchic". Some communication/reasoning will surely make each side understand better the pros/cons.
> Yeah, Jimb, I'm not sure I know what you mean by "undocumented error
> code values". Node does assume some familiarity with Posix error code
> values, but that's a very long and well-documented tradition.
> Actually, your gist is a perfect example of why fs.exists is a)
> unnecessary, and b) almost always the wrong idea. In the first case,
> if the file exists, but is not readable, then the fs.exists() will
> return false, and your program will act as if the file is *missing*,
> which is incorrect.
> On Wed, Aug 22, 2012 at 2:10 PM, Nathan Rajlich <nat...@tootallnate.net> wrote:
>> Checking "err.code" for "ENOENT" is the most cross-platform and
>> backwards compatible way to check for the existence of the file.
>> On Wed, Aug 22, 2012 at 1:29 PM, Jimb Esser <wastel...@gmail.com> wrote:
>>> Yeah, there are a lot of cases where "does not exists" as an "error" needs
>>> to be treated differently. I tried making a "read from this file, return a
>>> default value if it does not exist" function without using fs.exists, and
>>> was unable to do so efficiently without relying on undocumented error code
>>> values [1]. It's very unclear if that code will work on different versions
>>> of node let alone different operating systems. It's vitally important in
>>> cases like "rename this file to a backup before overwriting" that an "error"
>>> in the process is treated differently than "file does not exists", so
>>> fs.exists does serve a purpose, even if its signature could have been
>>> designed in a more conformant manner.
Why not just decorate fs.exists with arguments.caller.length and call it a
day? It seems like there are arguments on both sides here to accept the new
standard and the old tradition. Eventually phasing out the old tradition
has to happen ( especially since you know, not 1.0 or anything here ), but
i'm just curious if there's any resistance to that interim solution right
now. Seems like that could work, and polymorphism is not necessarily a
forsaken tradition in programming.
Also,
Why does GMail think that polymorphism is not a word? Seriously?
On Wed, Aug 22, 2012 at 6:45 PM, Scott Gonzįlez <scott.gonza...@gmail.com>wrote:
> Why not just decorate fs.exists with arguments.caller.length and call it a
> day? It seems like there are arguments on both sides here to accept the new
> standard and the old tradition. Eventually phasing out the old tradition
> has to happen ( especially since you know, not 1.0 or anything here ), but
> i'm just curious if there's any resistance to that interim solution right
> now. Seems like that could work, and polymorphism is not necessarily a
> forsaken tradition in programming.
> Also,
> Why does GMail think that polymorphism is not a word? Seriously?
> On Wed, Aug 22, 2012 at 6:45 PM, Scott Gonzįlez <scott.gonza...@gmail.com>wrote:
>> On Wed, Aug 22, 2012 at 6:34 PM, Dan Milon <danmi...@gmail.com> wrote:
>>> Isaac, i am curious why you believe fs.exists should stay as is.
> Why not just decorate fs.exists with arguments.caller.length and call it a
> day? It seems like there are arguments on both sides here to accept the new
> standard and the old tradition. Eventually phasing out the old tradition
> has to happen ( especially since you know, not 1.0 or anything here ), but
> i'm just curious if there's any resistance to that interim solution right
> now. Seems like that could work, and polymorphism is not necessarily a
> forsaken tradition in programming.
> Also,
> Why does GMail think that polymorphism is not a word? Seriously?
> On Wed, Aug 22, 2012 at 6:45 PM, Scott Gonzįlez <scott.gonza...@gmail.com>wrote:
>> On Wed, Aug 22, 2012 at 6:34 PM, Dan Milon <danmi...@gmail.com> wrote:
>>> Isaac, i am curious why you believe fs.exists should stay as is.
On Wed, Aug 22, 2012 at 8:36 PM, Stewart Mckinney <lordma...@gmail.com> wrote:
> Ah, nevermind. Realized why. :/
> On Wed, Aug 22, 2012 at 11:30 PM, Stewart Mckinney <lordma...@gmail.com>
> wrote:
>> Why not just decorate fs.exists with arguments.caller.length and call it a
>> day? It seems like there are arguments on both sides here to accept the new
>> standard and the old tradition. Eventually phasing out the old tradition has
>> to happen ( especially since you know, not 1.0 or anything here ), but i'm
>> just curious if there's any resistance to that interim solution right now.
>> Seems like that could work, and polymorphism is not necessarily a forsaken
>> tradition in programming.
>> Also,
>> Why does GMail think that polymorphism is not a word? Seriously?
>> On Wed, Aug 22, 2012 at 6:45 PM, Scott Gonzįlez <scott.gonza...@gmail.com>
>> wrote:
>>> On Wed, Aug 22, 2012 at 6:34 PM, Dan Milon <danmi...@gmail.com> wrote:
>>>> Isaac, i am curious why you believe fs.exists should stay as is.
On Wed, Aug 22, 2012 at 8:58 PM, Nathan Rajlich <nat...@tootallnate.net> wrote:
> callback.length
> On Wed, Aug 22, 2012 at 8:36 PM, Stewart Mckinney <lordma...@gmail.com> wrote:
>> Ah, nevermind. Realized why. :/
>> On Wed, Aug 22, 2012 at 11:30 PM, Stewart Mckinney <lordma...@gmail.com>
>> wrote:
>>> Why not just decorate fs.exists with arguments.caller.length and call it a
>>> day? It seems like there are arguments on both sides here to accept the new
>>> standard and the old tradition. Eventually phasing out the old tradition has
>>> to happen ( especially since you know, not 1.0 or anything here ), but i'm
>>> just curious if there's any resistance to that interim solution right now.
>>> Seems like that could work, and polymorphism is not necessarily a forsaken
>>> tradition in programming.
>>> Also,
>>> Why does GMail think that polymorphism is not a word? Seriously?
>>> On Wed, Aug 22, 2012 at 6:45 PM, Scott Gonzįlez <scott.gonza...@gmail.com>
>>> wrote:
>>>> On Wed, Aug 22, 2012 at 6:34 PM, Dan Milon <danmi...@gmail.com> wrote:
>>>>> Isaac, i am curious why you believe fs.exists should stay as is.
This suggested gained a lot of +1's so i want to talk about it a moment.
I don't think it's suitable to *remove* APIs that still exist from the docs or hide them from being enumerable.
There are just too many node programs out there now and people who want to understand existing code need to read the documentation for an API that *is still active* should be able to find and view it and to debug that API via test code in the repl which making non-enumerable makes annoying.
This just isn't the grown up way to handle a mistake or a deprecation.
We need to call out in the docs that 1) this exists and is still available 2) it should not be used 3) why it should not be used and links to doing things the "right" way. Pretending it doesn't exist when it still does is like pretending we never made this mistake even though it still works in node. Let's take responsibility for this and do what's best for all of the existing and future users of node.
-Mikeal
On Aug 20, 2012, at August 20, 20128:53 AM, Tim Caswell <t...@creationix.com> wrote:
> How about removing it from the docs and making it non-enumerable in
> the fs module. Then any new developers won't know it's there unless
> they are reading someone else's code. Or maybe in the docs simply say
> that it shouldn't be used and is only left there so as to not break
> old code. Also, how is this different from deprecation?
> On Sun, Aug 19, 2012 at 4:02 PM, Bert Belder <bertbel...@gmail.com> wrote:
>> On Sunday, August 19, 2012 8:23:53 PM UTC+2, Nuno Job wrote:
>>>>> Maybe a note in the docs tell people that fs.stat is a better choice?
>>> Good idea Mikeal. Deprecation console.error && pointing people to
>>> fs.stat in the docs should do the trick.
>> I don't see enough compelling reasons to deprecate it. I think a doc
>> addition that warns people about the funky signature and the anti-pattern
>> would suffice.
I'd accept a pull request that explains the oddness of fs.exists in
the documentation. Making it non-enumerable or removing it from the
docs is a bad idea, on further consideration.
I'd also accept a pull request that documents all the Posix error
codes, though really, that should probably be part of the libuv
documentation. (But writing docs for libuv is a much larger pull
request.)
On Wed, Aug 22, 2012 at 9:49 PM, Mikeal Rogers <mikeal.rog...@gmail.com> wrote:
> This suggested gained a lot of +1's so i want to talk about it a moment.
> I don't think it's suitable to *remove* APIs that still exist from the docs or hide them from being enumerable.
> There are just too many node programs out there now and people who want to understand existing code need to read the documentation for an API that *is still active* should be able to find and view it and to debug that API via test code in the repl which making non-enumerable makes annoying.
> This just isn't the grown up way to handle a mistake or a deprecation.
> We need to call out in the docs that 1) this exists and is still available 2) it should not be used 3) why it should not be used and links to doing things the "right" way. Pretending it doesn't exist when it still does is like pretending we never made this mistake even though it still works in node. Let's take responsibility for this and do what's best for all of the existing and future users of node.
> -Mikeal
> On Aug 20, 2012, at August 20, 20128:53 AM, Tim Caswell <t...@creationix.com> wrote:
>> How about removing it from the docs and making it non-enumerable in
>> the fs module. Then any new developers won't know it's there unless
>> they are reading someone else's code. Or maybe in the docs simply say
>> that it shouldn't be used and is only left there so as to not break
>> old code. Also, how is this different from deprecation?
>> On Sun, Aug 19, 2012 at 4:02 PM, Bert Belder <bertbel...@gmail.com> wrote:
>>> On Sunday, August 19, 2012 8:23:53 PM UTC+2, Nuno Job wrote:
>>>>>> Maybe a note in the docs tell people that fs.stat is a better choice?
>>>> Good idea Mikeal. Deprecation console.error && pointing people to
>>>> fs.stat in the docs should do the trick.
>>> I don't see enough compelling reasons to deprecate it. I think a doc
>>> addition that warns people about the funky signature and the anti-pattern
>>> would suffice.
> I'd accept a pull request that explains the oddness of fs.exists in > the documentation. Making it non-enumerable or removing it from the > docs is a bad idea, on further consideration.
> I'd also accept a pull request that documents all the Posix error > codes, though really, that should probably be part of the libuv > documentation. (But writing docs for libuv is a much larger pull > request.)
> On Wed, Aug 22, 2012 at 9:49 PM, Mikeal Rogers <mikeal...@gmail.com<javascript:>> > wrote: > > This suggested gained a lot of +1's so i want to talk about it a moment.
> > I don't think it's suitable to *remove* APIs that still exist from the > docs or hide them from being enumerable.
> > There are just too many node programs out there now and people who want > to understand existing code need to read the documentation for an API that > *is still active* should be able to find and view it and to debug that API > via test code in the repl which making non-enumerable makes annoying.
> > This just isn't the grown up way to handle a mistake or a deprecation.
> > We need to call out in the docs that 1) this exists and is still > available 2) it should not be used 3) why it should not be used and links > to doing things the "right" way. Pretending it doesn't exist when it still > does is like pretending we never made this mistake even though it still > works in node. Let's take responsibility for this and do what's best for > all of the existing and future users of node.
> > -Mikeal
> > On Aug 20, 2012, at August 20, 20128:53 AM, Tim Caswell < > t...@creationix.com <javascript:>> wrote:
> >> How about removing it from the docs and making it non-enumerable in > >> the fs module. Then any new developers won't know it's there unless > >> they are reading someone else's code. Or maybe in the docs simply say > >> that it shouldn't be used and is only left there so as to not break > >> old code. Also, how is this different from deprecation?
> >> On Sun, Aug 19, 2012 at 4:02 PM, Bert Belder <bertb...@gmail.com<javascript:>> > wrote: > >>> On Sunday, August 19, 2012 8:23:53 PM UTC+2, Nuno Job wrote:
> >>>>>> Maybe a note in the docs tell people that fs.stat is a better > choice?
> >>>> Good idea Mikeal. Deprecation console.error && pointing people to > >>>> fs.stat in the docs should do the trick.
> >>> I don't see enough compelling reasons to deprecate it. I think a doc > >>> addition that warns people about the funky signature and the > anti-pattern > >>> would suffice.
> fs: stability 3 (Stable) => Backwards compatibility is guaranteed.
How about this:
if (callback.length > 1) { callback(err, res);
} else { callback(res); }
Would that be okay? Might be an issue if the callback is declared without parameters and uses the arguments variable instead. With the code above old code would continue to work, but new code using only the arguments array would be surprised by only getting one parameter.
On Aug 23, 4:45 pm, Bruno Jouhier <bjouh...@gmail.com> wrote:
> fs: stability 3 (Stable) => Backwards compatibility is guaranteed.
> There was an opportunity to fix it when moving it from path to fs. But now
> it's too late!
> Well, that's just life!
As previously suggested, we could still add a note to fs.exists'
description to point people to fs.stat and let them know that
fs.exists shouldn't be used (and why) or at least that there can be
gotchas.