[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

difficulty with blocks

Johannes Ahl-mann

2/12/2005 11:31:00 PM

i am still in my early stages of ruby, so please forgive me any
blatantly lacking insight ;-))

i wonder how to divide responsibilities of block-driven methods in ruby.
in python i can divide the responsibilities of creating data and
filtering it using generators and the functional itertools. although
this is a lot of lately tacked on functionality i am struggling to
implement something similar in ruby.

--- python code (untested code, but should run ;-) ---

def fib:
a, b = 1, 1
while true:
yield a
a, b = b, a+b

import itertools
def fibUpTo(n):
return itertools.takeWhile(lambda i: i < n, fib())

--- a unified solution in ruby: ---

def fibUpTo n, &block
a, b = 1, 1
while a < n
block.call(a)
a, b = b, a+b
end
end

--- snip ---

i would really like to separate the creation of the fibonacci series
from the filtering. this should be possible in ruby, i just can't see it
right now ;-))
is maybe building a generator with the generator module an option?a

thx,
Johannes
3 Answers

Johannes Ahl-mann

2/12/2005 11:52:00 PM

0

hi,

sorry for answering my own post, but i am adopting ruby at an incredible
rate. i know python quite well and it took me literally mere minutes to
get the BASIC hang of blocks... i've been programming in ruby for 3
hours now and it already feels like home! not much cosier than python,
but the block closures and the possibility of continuations drags me
into ruby nonetheless ;-)

well, i've got a rather satisfactory solution to my problem and would now like
to ask whether my implementation can be considered "the ruby way" or if it
feels rather strange to the senior rubiists (i.e. people who have
programmed in ruby for more than 3 hours) *ggg*


### snip ###


def fib_block &block
a, b = 1, 1
while true:
block.call(a)
a, b = b, a+b
end
end

require 'generator'
def fibUpTo n, &block
fibs = Generator.new do |g|
fib_block {|val| g.yield val}
end

while (f = fibs.next()) < n
block.call(f)
end
end

def into(anArray)
return proc {|val| anArray << val}
end
fibUpTo 20, &into(a = [])
puts a


### snip ###

thx and forgive me for answering my own questions. i really shouldn't do
that ;-))

Johannes

P.S.: what is it with the implicit blocks in ruby. i am aware that many
people seem not to be explicitely passing the block into a function, but
i really find that distracting and too much of a perl idiom. is my way
alright, or was it unidiomatic??

P.P.S: is there a better way to write "fib_block {|val| g.yield val}"?
maybe something like "fib_block.apply(g.yield)" or so. i guess not, but
the repetition bothers me!

Stefan Lang

2/13/2005 12:30:00 AM

0

Johannes Ahl-mann wrote:

> hi,
>
> sorry for answering my own post, but i am adopting ruby at an incredible
> rate. i know python quite well and it took me literally mere minutes to
> get the BASIC hang of blocks... i've been programming in ruby for 3
> hours now and it already feels like home! not much cosier than python,
> but the block closures and the possibility of continuations drags me
> into ruby nonetheless ;-)
>
> well, i've got a rather satisfactory solution to my problem and would now
> like to ask whether my implementation can be considered "the ruby way" or
> if it feels rather strange to the senior rubiists (i.e. people who have
> programmed in ruby for more than 3 hours) *ggg*
>
>
> ### snip ###
>
>
> def fib_block &block
> a, b = 1, 1
> while true:
> block.call(a)
> a, b = b, a+b
> end
> end
>
> require 'generator'
> def fibUpTo n, &block
> fibs = Generator.new do |g|
> fib_block {|val| g.yield val}
> end
>
> while (f = fibs.next()) < n
> block.call(f)
> end
> end
>
> def into(anArray)
> return proc {|val| anArray << val}
> end
> fibUpTo 20, &into(a = [])
> puts a
>

A shorter version without the generator library would be:
##################################################
#!/usr/bin/ruby

def fib
a, b = 1, 1
loop {
yield a
a, b = b, a + b
}
end

def fibUpTo n
fib { |val|
break if val > n
yield val
}
end

a = []
fibUpTo(20) { |val| a << val }
puts a
##################################################

>
> ### snip ###
>
> thx and forgive me for answering my own questions. i really shouldn't do
> that ;-))
>
> Johannes
>
> P.S.: what is it with the implicit blocks in ruby. i am aware that many
> people seem not to be explicitely passing the block into a function, but
> i really find that distracting and too much of a perl idiom. is my way
> alright, or was it unidiomatic??
>
> P.P.S: is there a better way to write "fib_block {|val| g.yield val}"?
> maybe something like "fib_block.apply(g.yield)" or so. i guess not, but
> the repetition bothers me!

Johannes Ahl-mann

2/13/2005 1:11:00 AM

0

> A shorter version without the generator library would be:
> ##################################################
> #!/usr/bin/ruby
>
> def fib
> a, b = 1, 1
> loop {
> yield a
> a, b = b, a + b
> }
> end
>
> def fibUpTo n
> fib { |val|
> break if val > n
> yield val
> }
> end
>
> a = []
> fibUpTo(20) { |val| a << val }
> puts a
> ##################################################
>

thx, this helped a lot. i wasn't aware that one could use "break" inside
a block... this looks very readable and natural.

Johannes