Reading String Data as a File

Btw, this inspired me to Toy example of simpler loop nesting ยท GitHub

:slight_smile:

Cheers

robert

ยทยทยท

2010/7/1 Robert Klemme <shortcutter@googlemail.com>:

2010/7/1 James Edward Gray II <james@graysoftinc.com>:

On Jun 30, 2010, at 10:41 AM, Brian Candler wrote:

James Edward Gray II wrote:

I'm open to suggestions and I do take patches.

Specifically, I'd like to see how to parse CSV from stdin. You provide
an example in the opposite direction:

# FCSV($stderr) { |csv_err| csv_err << %w{my data here} } # to
$stderr

On Jun 30, 2010, at 11:35 AM, Robert Klemme wrote:

On 30.06.2010 17:05, James Edward Gray II wrote:

Do you think it would help if I added Wrapping an IO under the
Shortcut Interface on this page?

http://fastercsv.rubyforge.org/classes/FasterCSV.html

+1

Better?

http://fastercsv.rubyforge.org/classes/FasterCSV.html

Perfect! Do you think it is a good idea to also allow an IO as
argument to foreach so we can save a block?

FCSV($stdin) { |csv_in| csv_in.each { |row| p row } } # from $stdin

would become

FCSV.foreach($stdin) { |row| p row } # from $stdin

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

I would rather not go that far. The standard CSV library for Ruby 1.8 varied its interface slightly from the IO methods I assumed it meant to imitate. For example, open() was essentially foreach() when you passed an "r" mode. This always bothered me.

We don't need two blocks though. I showed it that way in the documentation for consistency (to hopefully make it easier to remember), but this works:

$ echo -e 'a,b,c' | ruby -rubygems -e 'require "faster_csv"; FCSV($stdin).each { |row| p row }'
["a", "b", "c"]

James Edward Gray II

ยทยทยท

On Jul 1, 2010, at 4:02 AM, Robert Klemme wrote:

2010/7/1 James Edward Gray II <james@graysoftinc.com>:

On Jun 30, 2010, at 10:41 AM, Brian Candler wrote:

James Edward Gray II wrote:

I'm open to suggestions and I do take patches.

Specifically, I'd like to see how to parse CSV from stdin. You provide
an example in the opposite direction:

# FCSV($stderr) { |csv_err| csv_err << %w{my data here} } # to
$stderr

On Jun 30, 2010, at 11:35 AM, Robert Klemme wrote:

On 30.06.2010 17:05, James Edward Gray II wrote:

Do you think it would help if I added Wrapping an IO under the
Shortcut Interface on this page?

http://fastercsv.rubyforge.org/classes/FasterCSV.html

+1

Better?

http://fastercsv.rubyforge.org/classes/FasterCSV.html

Perfect! Do you think it is a good idea to also allow an IO as
argument to foreach so we can save a block?

FCSV($stdin) { |csv_in| csv_in.each { |row| p row } } # from $stdin

would become

FCSV.foreach($stdin) { |row| p row } # from $stdin

Robert Klemme wrote:

The non block form obviously returns the Tempfile instance and if you
want it to be returned from the block what stops you from explicitly
returning it?

Only that it's a bit verbose:

  tf = nil
  Tempfile.open(...) do |io|
    tf = io
    ...
  end
  puts tf.path

http://redmine.ruby-lang.org/issues/show/504

IMHO the method with block should return whatever the implementor of the
block chooses. That is far more reusable than always returning the
Tempfile.

Maybe that's what the accepted patch does - I haven't tested it. It
would be consistent with File.open { ... } if it worked that way.

Anyway, I think we're talking about minutiae. You say that one should
close the file at the earliest opportunity to "save resources", but the
only resource we're talking about is one slot in the kernel file
descriptor table, and most apps aren't going to be constrained by that.

ยทยทยท

--
Posted via http://www.ruby-forum.com/\.

Good point. Thank you for consideration of my suggestion.

Kind regards

  robert

ยทยทยท

On 01.07.2010 16:14, James Edward Gray II wrote:

On Jul 1, 2010, at 4:02 AM, Robert Klemme wrote:

2010/7/1 James Edward Gray II<james@graysoftinc.com>:

On Jun 30, 2010, at 10:41 AM, Brian Candler wrote:

James Edward Gray II wrote:

I'm open to suggestions and I do take patches.

Specifically, I'd like to see how to parse CSV from stdin. You
provide an example in the opposite direction:

# FCSV($stderr) { |csv_err| csv_err<< %w{my data here} }
# to $stderr

On Jun 30, 2010, at 11:35 AM, Robert Klemme wrote:

On 30.06.2010 17:05, James Edward Gray II wrote:

Do you think it would help if I added Wrapping an IO under
the Shortcut Interface on this page?

http://fastercsv.rubyforge.org/classes/FasterCSV.html

+1

Better?

http://fastercsv.rubyforge.org/classes/FasterCSV.html

Perfect! Do you think it is a good idea to also allow an IO as
argument to foreach so we can save a block?

FCSV($stdin) { |csv_in| csv_in.each { |row| p row } } # from
$stdin

would become

FCSV.foreach($stdin) { |row| p row } # from $stdin

I would rather not go that far. The standard CSV library for Ruby
1.8 varied its interface slightly from the IO methods I assumed it
meant to imitate. For example, open() was essentially foreach() when
you passed an "r" mode. This always bothered me.

We don't need two blocks though. I showed it that way in the
documentation for consistency (to hopefully make it easier to
remember), but this works:

$ echo -e 'a,b,c' | ruby -rubygems -e 'require "faster_csv";
FCSV($stdin).each { |row| p row }' ["a", "b", "c"]

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Robert Klemme wrote:

The non block form obviously returns the Tempfile instance and if you
want it to be returned from the block what stops you from explicitly
returning it?

Only that it's a bit verbose:

   tf = nil
   Tempfile.open(...) do |io|
     tf = io
     ...
   end
   puts tf.path

No, I was talking about the other version which returns whatever the block returns. You would do

   tf = Tempfile.open(...) do |io|
     ...
     io
   end
   puts tf.path

http://redmine.ruby-lang.org/issues/show/504

Apparently people differ in their preferences.

IMHO the method with block should return whatever the implementor of the
block chooses. That is far more reusable than always returning the
Tempfile.

Maybe that's what the accepted patch does - I haven't tested it. It
would be consistent with File.open { ... } if it worked that way.

Exactly that is what the patch does:

http://redmine.ruby-lang.org/repositories/diff/ruby-19?rev=19454

Anyway, I think we're talking about minutiae. You say that one should
close the file at the earliest opportunity to "save resources", but the
only resource we're talking about is one slot in the kernel file
descriptor table, and most apps aren't going to be constrained by that.

That's true. But I also have seen issues caused by files being opened more than once by the same process. Plus, you'll notice much faster if you try to write to the tempfile after you thought you were done when you close the file. If the code is more complicated these bugs can be hard to track. How much simpler is it if you see this:

irb(main):006:0> Tempfile.open "x" do |io|
irb(main):007:1* p io
irb(main):008:1> io.puts "hello"
irb(main):009:1> io.close
irb(main):010:1> io.puts "world"
irb(main):011:1> end
#<File:C:/Users/Robert/x20100630-4456-1ixsj0i-0>
IOError: closed stream
         from (irb):10:in `block in irb_binding'
         from /usr/local/lib/ruby19/1.9.1/tempfile.rb:199:in `open'
         from (irb):6
         from /usr/local/bin/irb19:12:in `<main>'

It's probably not that big a deal but I believe such discussions bring benefit to the community by presenting alternative solutions to a problem along with arguments. I always like this food for thought. Thanks for sharing your thoughts!

Kind regards

  robert

ยทยทยท

On 30.06.2010 20:26, Brian Candler wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/