difficulty with blocks

Discussion in 'Ruby' started by Johannes Ahl-mann, Feb 12, 2005.

  1. 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
     
    Johannes Ahl-mann, Feb 12, 2005
    #1
    1. Advertising

  2. 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!
     
    Johannes Ahl-mann, Feb 12, 2005
    #2
    1. Advertising

  3. Johannes Ahl-mann

    Stefan Lang Guest

    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!
     
    Stefan Lang, Feb 13, 2005
    #3
  4. > 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
     
    Johannes Ahl-mann, Feb 13, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bjoern Wolfgardt
    Replies:
    0
    Views:
    444
    Bjoern Wolfgardt
    Jul 16, 2003
  2. Samridhi Kumar Shukla
    Replies:
    1
    Views:
    532
    Alvin Bruney
    Nov 30, 2003
  3. Arjen
    Replies:
    3
    Views:
    455
    Scott Allen
    Feb 27, 2005
  4. matt
    Replies:
    1
    Views:
    285
    George Ogata
    Aug 6, 2004
  5. Steven Taylor
    Replies:
    9
    Views:
    271
    Brian Candler
    Apr 27, 2009
Loading...

Share This Page