Sweet Lord!

Why haven't I thought of this before?

   class Terminal
     include Enumerable

     def each(&block)
       while input = gets
         block.call(input.chomp)
       end
     end
   end

   terminal = Terminal.new

   # terminate the loop with ctrl-d, or whatever works for you.
   terminal.entries
   terminal.map{|line| line.to_sym}
   terminal.inject(""){|str, line| str << line}

Yet another epiphany. Thank you, Ruby.

Cheers,
Daniel

Daniel Schierbeck wrote:

Why haven't I thought of this before?

   class Terminal
     include Enumerable

     def each(&block)
       while input = gets
         block.call(input.chomp)
       end
     end

  def each
    while input = gets
      yield input.chomp
    end
  end

Is chomp really worth a new class? Note that you can do all of this
already with an IO:

$ ruby -e 'STDIN.each {|line| p line}'
dd
"dd\n"
ff
"ff\n"

$ ruby -e 'p STDIN.entries'
dd
ff
["dd\n", "ff\n"]

$ ruby -e 'p STDIN.map {|line| line.inspect}'
ddd
sss
["\"ddd\\n\"", "\"sss\\n\""]

Kind regards

robert

···

2006/7/8, Daniel Schierbeck <daniel.schierbeck@gmail.com>:

Why haven't I thought of this before?

   class Terminal
     include Enumerable

     def each(&block)
       while input = gets
         block.call(input.chomp)
       end
     end
   end

   terminal = Terminal.new

   # terminate the loop with ctrl-d, or whatever works for you.
   terminal.entries
   terminal.map{|line| line.to_sym}
   terminal.inject(""){|str, line| str << line}

Yet another epiphany. Thank you, Ruby.

--
Have a look: Robert K. | Flickr

William James wrote:

Daniel Schierbeck wrote:

Why haven't I thought of this before?

   class Terminal
     include Enumerable

     def each(&block)
       while input = gets
         block.call(input.chomp)
       end
     end

  def each
    while input = gets
      yield input.chomp
    end
  end

Thanks! Yes, that's of course a whole lot faster.

Cheers,
Daniel

Equivilent code, actually. It's a case of "you say tomaTOE I say tomAHto"
Personally, I tend to prefer the 'block.call' because you explicitly
say you're passing in a block in the definition of the method, so if
someone is reading your code they can easily tell that the method
takes a block. In the case of yield you might need to read through a
good bit of code before you find out that the method takes a block.

Phil

···

On 7/8/06, William James <w_a_x_man@yahoo.com> wrote:

Daniel Schierbeck wrote:
> Why haven't I thought of this before?
>
> class Terminal
> include Enumerable
>
> def each(&block)
> while input = gets
> block.call(input.chomp)
> end
> end

  def each
    while input = gets
      yield input.chomp
    end
  end

Robert Klemme wrote:

Is chomp really worth a new class? ...

I'm not sure, but it's a great way to show off Ruby's flexibility.

Cheers,
Daniel

It looks even cooler like this:

   class Terminal
     class << self
       include Enumerable

       def each
         while input = gets
           yield input.chomp
         end
       end
     end
   end

   Terminal.entries.join(', ')

Ahh, the possibilities!

Cheers,
Daniel

Phil Tomson wrote:

  def each
    while input = gets
      yield input.chomp
    end
  end

Equivilent code, actually. It's a case of "you say tomaTOE I say tomAHto"
Personally, I tend to prefer the 'block.call' because you explicitly
say you're passing in a block in the definition of the method, so if
someone is reading your code they can easily tell that the method
takes a block. In the case of yield you might need to read through a
good bit of code before you find out that the method takes a block.

Phil

block.call is significantly slower since conversion from block to Proc object involves copying references of a closure to Proc instance.

lopex

Phil Tomson wrote:

···

On 7/8/06, William James <w_a_x_man@yahoo.com> wrote:

Daniel Schierbeck wrote:
> Why haven't I thought of this before?
>
> class Terminal
> include Enumerable
>
> def each(&block)
> while input = gets
> block.call(input.chomp)
> end
> end

  def each
    while input = gets
      yield input.chomp
    end
  end

Equivilent code, actually. It's a case of "you say tomaTOE I say tomAHto"

Actually, the `yield' version is significantly faster. When using the `&block' syntax, a Proc object is created for each iteration. From what I've gathered, that doesn't happen when using `yield'.

Cheers,
Daniel

Hi --

Daniel Schierbeck wrote:
> Why haven't I thought of this before?
>
> class Terminal
> include Enumerable
>
> def each(&block)
> while input = gets
> block.call(input.chomp)
> end
> end

  def each
    while input = gets
      yield input.chomp
    end
  end

Equivilent code, actually. It's a case of "you say tomaTOE I say tomAHto"
Personally, I tend to prefer the 'block.call' because you explicitly
say you're passing in a block in the definition of the method, so if
someone is reading your code they can easily tell that the method
takes a block. In the case of yield you might need to read through a
good bit of code before you find out that the method takes a block.

It does seem that yielding is faster; note the effect of turning the
block into a Proc object:

require 'benchmark'
include Benchmark

n = 100000

def y
end

def b(&block)
end

bm do |x|
   x.report("call") { n.times { b { } } }
   x.report("yield") { n.times { y { } } }
end

# Output:

       user system total real
call 1.860000 0.040000 1.900000 ( 2.874001)
yield 0.220000 0.000000 0.220000 ( 0.249164)

David

···

On Sun, 9 Jul 2006, Phil Tomson wrote:

On 7/8/06, William James <w_a_x_man@yahoo.com> wrote:

--
  "To fully realize the potential of Rails, it's crucial that you take
    the time to fully understand Ruby--and with "Ruby for Rails" David
       has provided just what you need to help you achieve that goal."
       -- DAVID HEINEMEIER HANSSON, in the foreword to RUBY FOR RAILS.
  Complete foreword & sample chapters at http://www.manning.com/black\!

Phil Tomson wrote:

takes a block. In the case of yield you might need to read through a
good bit of code before you find out that the method takes a block.

Note that rdoc can scan for yields, and document them.

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Daniel Schierbeck wrote:

William James wrote:
> Daniel Schierbeck wrote:
>> Why haven't I thought of this before?
>>
>> class Terminal
>> include Enumerable
>>
>> def each(&block)
>> while input = gets
>> block.call(input.chomp)
>> end
>> end
>
> def each
> while input = gets
> yield input.chomp
> end
> end

Thanks! Yes, that's of course a whole lot faster.

Cheers,
Daniel

I didn't know that it would be faster; I only knew that using &block
is SO MUCH UGLIER!

I prefer:

$stdin.readlines.join ', '

···

On Jul 9, 2006, at 6:45 AM, Daniel Schierbeck wrote:

It looks even cooler like this:

  class Terminal
    class << self
      include Enumerable

      def each
        while input = gets
          yield input.chomp
        end
      end
    end
  end

  Terminal.entries.join(', ')

Ahh, the possibilities!

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

That is a fairly significant difference, so maybe I should revise my
statement to say that the two different ways acheive the same effect
ignoring differences in runtime :wink:

Phil

···

On 7/8/06, dblack@wobblini.net <dblack@wobblini.net> wrote:

Hi --

On Sun, 9 Jul 2006, Phil Tomson wrote:

> On 7/8/06, William James <w_a_x_man@yahoo.com> wrote:
>> Daniel Schierbeck wrote:
>> > Why haven't I thought of this before?
>> >
>> > class Terminal
>> > include Enumerable
>> >
>> > def each(&block)
>> > while input = gets
>> > block.call(input.chomp)
>> > end
>> > end
>>
>> def each
>> while input = gets
>> yield input.chomp
>> end
>> end
>
> Equivilent code, actually. It's a case of "you say tomaTOE I say tomAHto"
> Personally, I tend to prefer the 'block.call' because you explicitly
> say you're passing in a block in the definition of the method, so if
> someone is reading your code they can easily tell that the method
> takes a block. In the case of yield you might need to read through a
> good bit of code before you find out that the method takes a block.

It does seem that yielding is faster; note the effect of turning the
block into a Proc object:

require 'benchmark'
include Benchmark

n = 100000

def y
end

def b(&block)
end

bm do |x|
   x.report("call") { n.times { b { } } }
   x.report("yield") { n.times { y { } } }
end

# Output:

       user system total real
call 1.860000 0.040000 1.900000 ( 2.874001)
yield 0.220000 0.000000 0.220000 ( 0.249164)

William James wrote:

Daniel Schierbeck wrote:

William James wrote:

Daniel Schierbeck wrote:

Why haven't I thought of this before?

   class Terminal
     include Enumerable

     def each(&block)
       while input = gets
         block.call(input.chomp)
       end
     end

  def each
    while input = gets
      yield input.chomp
    end
  end

Thanks! Yes, that's of course a whole lot faster.

Cheers,
Daniel

I didn't know that it would be faster; I only knew that using &block
is SO MUCH UGLIER!

That, my friend, is a matter of taste.

Cheers,
Daniel

Daniel Schierbeck wrote:

William James wrote:

I didn't know that it would be faster; I only knew that using &block
is SO MUCH UGLIER!

That, my friend, is a matter of taste.

There is nothing without a purpose. Consider an object method that takes a block and it doesn't want to execute it immediately. What would you do without a &block ?

lopex

Daniel Schierbeck wrote:

William James wrote:
> Daniel Schierbeck wrote:
>> William James wrote:
>>> Daniel Schierbeck wrote:
>>>> Why haven't I thought of this before?
>>>>
>>>> class Terminal
>>>> include Enumerable
>>>>
>>>> def each(&block)
>>>> while input = gets
>>>> block.call(input.chomp)
>>>> end
>>>> end
>>> def each
>>> while input = gets
>>> yield input.chomp
>>> end
>>> end
>> Thanks! Yes, that's of course a whole lot faster.
>>
>>
>> Cheers,
>> Daniel
>
> I didn't know that it would be faster; I only knew that using &block
> is SO MUCH UGLIER!

That, my friend, is a matter of taste.

Some have good taste. Some have very bad taste; they relish a
turd more than a chocolate bar or enjoy needlessly using &block.

Marcin Mielzynski wrote:

Daniel Schierbeck wrote:
> William James wrote:
>> I didn't know that it would be faster; I only knew that using &block
>> is SO MUCH UGLIER!
>
> That, my friend, is a matter of taste.
>

There is nothing without a purpose. Consider an object method that takes
a block and it doesn't want to execute it immediately. What would you do
without a &block ?

Utterly illogical. That is like saying that sometimes we must amputate
a
man's foot in order to save his life, and that therefore we must always
amputate a man's foot.

But, you have to admit, it does stand to reason that feces would require more
relish than a Hershey's.

_why

···

On Sun, Jul 09, 2006 at 11:25:11AM +0900, William James wrote:

Some have good taste. Some have very bad taste; they relish a
turd more than a chocolate bar or enjoy needlessly using &block.

William James wrote:

Marcin Mielzynski wrote:

Daniel Schierbeck wrote:

William James wrote:

I didn't know that it would be faster; I only knew that using &block
is SO MUCH UGLIER!

That, my friend, is a matter of taste.

There is nothing without a purpose. Consider an object method that takes
a block and it doesn't want to execute it immediately. What would you do
without a &block ?

Utterly illogical. That is like saying that sometimes we must amputate
a
man's foot in order to save his life, and that therefore we must always
amputate a man's foot.

I think he was trying to say that there are times when `yield' is the best choice, and there are times when `&block' is. It all depends on the situation.

Cheers,
Daniel