[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Sweet Lord!

Daniel Schierbeck

7/8/2006 5:16:00 PM

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
22 Answers

William James

7/8/2006 7:03:00 PM

0

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

Daniel Schierbeck

7/8/2006 7:09:00 PM

0

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

rubyfan

7/8/2006 7:16:00 PM

0

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.


Phil

Marcin Mielzynski

7/8/2006 7:23:00 PM

0

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

Daniel Schierbeck

7/8/2006 7:28:00 PM

0

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

dblack

7/8/2006 7:32:00 PM

0

rubyfan

7/8/2006 7:46:00 PM

0

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)
>

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 ;-)

Phil

Joel VanderWerf

7/8/2006 10:41:00 PM

0

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

William James

7/8/2006 11:09:00 PM

0


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!

Daniel Schierbeck

7/8/2006 11:27:00 PM

0

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