Suggestion: file:write() and other methods should return file

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Suggestion: file:write() and other methods should return file

Rena
I just noticed that file:write() returns true on success (though the
manual doesn't mention any return value). If it were changed to return
the file, you could write:
> assert(io.open('foo', 'a+')):write('foooo'):close()

instead of:
> local file = assert(io.open('foo', 'a+'))
> file:write('foooo')
> file:close()

One simple change allows for much shorter, neater code... seems pretty
Lua-ish to me! :) Other file methods such as file:flush() and
file:setvbuf() could benefit from the same change. file:seek() as
well, but then you'd be breaking the API (you'd have to return file
and position instead of just position). file:read() maybe if you have
some "read into a table" or "pass the read data to a callback
function", but now we're getting kind of out there... :)

--
Sent from my toaster.

Reply | Threaded
Open this post in threaded view
|

Re: Suggestion: file:write() and other methods should return file

Marc Balmer
Am 02.07.2011 12:53, schrieb HyperHacker:

> I just noticed that file:write() returns true on success (though the
> manual doesn't mention any return value). If it were changed to return
> the file, you could write:
>> assert(io.open('foo', 'a+')):write('foooo'):close()
>
> instead of:
>> local file = assert(io.open('foo', 'a+'))
>> file:write('foooo')
>> file:close()
>
> One simple change allows for much shorter, neater code... seems pretty
> Lua-ish to me! :) Other file methods such as file:flush() and
> file:setvbuf() could benefit from the same change. file:seek() as
> well, but then you'd be breaking the API (you'd have to return file
> and position instead of just position). file:read() maybe if you have
> some "read into a table" or "pass the read data to a callback
> function", but now we're getting kind of out there... :)

How do you catch an error then?  Not everyone ignores the return code
like you do in your example above...


Reply | Threaded
Open this post in threaded view
|

Re: Suggestion: file:write() and other methods should return file

Rebel Neurofog
On Sat, Jul 2, 2011 at 2:56 PM, Marc Balmer <[hidden email]> wrote:

> Am 02.07.2011 12:53, schrieb HyperHacker:
>> I just noticed that file:write() returns true on success (though the
>> manual doesn't mention any return value). If it were changed to return
>> the file, you could write:
>>> assert(io.open('foo', 'a+')):write('foooo'):close()
>>
>> instead of:
>>> local file = assert(io.open('foo', 'a+'))
>>> file:write('foooo')
>>> file:close()
>>
>> One simple change allows for much shorter, neater code... seems pretty
>> Lua-ish to me! :) Other file methods such as file:flush() and
>> file:setvbuf() could benefit from the same change. file:seek() as
>> well, but then you'd be breaking the API (you'd have to return file
>> and position instead of just position). file:read() maybe if you have
>> some "read into a table" or "pass the read data to a callback
>> function", but now we're getting kind of out there... :)
>
> How do you catch an error then?  Not everyone ignores the return code
> like you do in your example above...

assert (assert(io.open('foo', 'a+')):write('foooo')):close()

Reply | Threaded
Open this post in threaded view
|

Re: Suggestion: file:write() and other methods should return file

Rena
In reply to this post by Marc Balmer
On Sat, Jul 2, 2011 at 04:56, Marc Balmer <[hidden email]> wrote:

> Am 02.07.2011 12:53, schrieb HyperHacker:
>> I just noticed that file:write() returns true on success (though the
>> manual doesn't mention any return value). If it were changed to return
>> the file, you could write:
>>> assert(io.open('foo', 'a+')):write('foooo'):close()
>>
>> instead of:
>>> local file = assert(io.open('foo', 'a+'))
>>> file:write('foooo')
>>> file:close()
>>
>> One simple change allows for much shorter, neater code... seems pretty
>> Lua-ish to me! :) Other file methods such as file:flush() and
>> file:setvbuf() could benefit from the same change. file:seek() as
>> well, but then you'd be breaking the API (you'd have to return file
>> and position instead of just position). file:read() maybe if you have
>> some "read into a table" or "pass the read data to a callback
>> function", but now we're getting kind of out there... :)
>
> How do you catch an error then?  Not everyone ignores the return code
> like you do in your example above...
>
>
>

It would still return nil and error message on failure. That does mean
if you write something like I did you'd get an "attempt to index nil"
error, but you can fix that with more assertion (as Rebel Neurofog
showed) or wrapping it in a pcall().

--
Sent from my toaster.

Reply | Threaded
Open this post in threaded view
|

Re: Suggestion: file:write() and other methods should return file

steve donovan
In reply to this post by Rena
On Sat, Jul 2, 2011 at 12:53 PM, HyperHacker <[hidden email]> wrote:
> I just noticed that file:write() returns true on success (though the
> manual doesn't mention any return value).

Ah, but in 5.2 it does return the file object, allowing chaining:

Lua 5.2.0 (beta)  Copyright (C) 1994-2011 Lua.org, PUC-Rio
> = io.write 'hello\n'
hello
file (000007FEFD972AB0)

steve d.

Reply | Threaded
Open this post in threaded view
|

Re: Suggestion: file:write() and other methods should return file

Rena
On Sat, Jul 2, 2011 at 07:34, steve donovan <[hidden email]> wrote:

> On Sat, Jul 2, 2011 at 12:53 PM, HyperHacker <[hidden email]> wrote:
>> I just noticed that file:write() returns true on success (though the
>> manual doesn't mention any return value).
>
> Ah, but in 5.2 it does return the file object, allowing chaining:
>
> Lua 5.2.0 (beta)  Copyright (C) 1994-2011 Lua.org, PUC-Rio
>> = io.write 'hello\n'
> hello
> file (000007FEFD972AB0)
>
> steve d.
>
>

Aha, so my time machine worked! :D

--
Sent from my toaster.

Reply | Threaded
Open this post in threaded view
|

Re: Suggestion: file:write() and other methods should return file

Mark Hamburg
In reply to this post by Marc Balmer
On Jul 2, 2011, at 3:56 AM, Marc Balmer wrote:

> Am 02.07.2011 12:53, schrieb HyperHacker:
>> I just noticed that file:write() returns true on success (though the
>> manual doesn't mention any return value). If it were changed to return
>> the file, you could write:
>>> assert(io.open('foo', 'a+')):write('foooo'):close()
>>
>> instead of:
>>> local file = assert(io.open('foo', 'a+'))
>>> file:write('foooo')
>>> file:close()
>>
>> One simple change allows for much shorter, neater code... seems pretty
>> Lua-ish to me! :) Other file methods such as file:flush() and
>> file:setvbuf() could benefit from the same change. file:seek() as
>> well, but then you'd be breaking the API (you'd have to return file
>> and position instead of just position). file:read() maybe if you have
>> some "read into a table" or "pass the read data to a callback
>> function", but now we're getting kind of out there... :)
>
> How do you catch an error then?  Not everyone ignores the return code
> like you do in your example above...

Monadic file error values? In the event of an error, it returns an object containing the error code which supports the same file operations but doesn't actually do anything. (TBD whether it passes through close and flush, it probably should.) Then you write:

io.open( 'foo', 'a+' ):write('fooo'):close():assert()

Here assert is a method that by default returns self but in the case of a monadic error value throws.

I rather like this in some ways, but I'm not particularly fond of having some methods pass through and some not since that makes the spec rather unclear.

Mark


Reply | Threaded
Open this post in threaded view
|

Re: Suggestion: file:write() and other methods should return file

Lorenzo Donati-2
In reply to this post by Rena
On 02/07/2011 16.26, HyperHacker wrote:

> On Sat, Jul 2, 2011 at 07:34, steve donovan<[hidden email]>  wrote:
>> On Sat, Jul 2, 2011 at 12:53 PM, HyperHacker<[hidden email]>  wrote:
>>> I just noticed that file:write() returns true on success (though the
>>> manual doesn't mention any return value).
>>
>> Ah, but in 5.2 it does return the file object, allowing chaining:
>>
>> Lua 5.2.0 (beta)  Copyright (C) 1994-2011 Lua.org, PUC-Rio
>>> = io.write 'hello\n'
>> hello
>> file (000007FEFD972AB0)
>>
>> steve d.
>>
>>
>
> Aha, so my time machine worked! :D
>
This reminds me of an old English TV series "Doctor Who", who had a time
machine in the shape of a classic English telephone booth.

Given the source of your mails, I suspect yours is in the shape of a
toaster ;-) :-D

Cheers.
-- Lorenzo

Reply | Threaded
Open this post in threaded view
|

Re: Suggestion: file:write() and other methods should return file

Javier Guerra Giraldez
In reply to this post by Mark Hamburg
On Sat, Jul 2, 2011 at 10:11 AM, Mark Hamburg <[hidden email]> wrote:
> io.open( 'foo', 'a+' ):write('fooo'):close():assert()

very interesting.  i'd chose to have a single error class, that
returns self on _every_ function except :err(), that returns nil,error
and :assert() that fails

is that style common in any language/library you know?

--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: Suggestion: file:write() and other methods should return file

steve donovan
On Sat, Jul 2, 2011 at 6:09 PM, Javier Guerra Giraldez
<[hidden email]> wrote:
> very interesting.  i'd chose to have a single error class, that
> returns self on _every_ function except :err(), that returns nil,error
> and :assert() that fails

And it's pretty easy to do:

-- err.lua
local function errf(self)
  return nil,self.msg
end

local function passthru(self,...)
  return self
end

local err = {
  __index = function(self,k)
    if k == 'err' then
      return errf
    elseif k == 'assert' then error(self.msg,2)
    else
      return passthru
    end
  end
}

function err.new(msg)
  return setmetatable({msg=msg},err)
end

print(err.new("borked"):meth(2):another():err())
err.new("throws"):stuff(42,'hello'):assert()
-----------------
--->
nil     borked
lua: err.lua:25: throws
stack traceback:
        [C]: in function 'error'
       ....

You can get Mark's style easily by monkey-patching the io library.
(The fact that most people would react in horror to this idea is one
measure of the difference between the Lua and Ruby communities)

steve d.

Reply | Threaded
Open this post in threaded view
|

Re: Suggestion: file:write() and other methods should return file

Tony Finch
In reply to this post by Javier Guerra Giraldez
Javier Guerra Giraldez <[hidden email]> wrote:
> On Sat, Jul 2, 2011 at 10:11 AM, Mark Hamburg <[hidden email]> wrote:
> >
> > io.open( 'foo', 'a+' ):write('fooo'):close():assert()
>
> very interesting.  i'd chose to have a single error class, that
> returns self on _every_ function except :err(), that returns nil,error
> and :assert() that fails
>
> is that style common in any language/library you know?

It's pretty straightforward to do this with Haskell. There's a trivial
implementation of the "maybe monad" in the standard prelude, which either
succeeds with a value or fails with nothing - which is a bit feeble as
error indicators go, but it gives you the idea.

Tony.
--
f.anthony.n.finch  <[hidden email]>  http://dotat.at/
South Utsire, East Forties: Northerly 5 or 6, becoming variable 4 later.
Moderate becoming slight. Mainly fair. Moderate or good.