blocks and late evaluation

Discussion in 'Ruby' started by Vassilis Vatikiotis, Sep 5, 2011.

  1. hi all,

    my question is in the context of sinatra but it's a blocks question really.

    I have configure block in sinatra (configure blocks in sinatra run only once, upon initialisation). There, I want to load some database records in memory. So I do:
    configure do
    set :keys do
    DB.all.map { |record| record.field }
    end
    end

    Whenever I access the class level variable :keys I get a DB query. Whereas if, inside that configure block, I do:

    keys = DB.all.map { |record| record.field }
    set :keys, keys

    there are no DB queries, I can even stop the database daemon and my app will go on.

    Now I'm *almost* certain that it's not a sinatra issue but my ruby block ignorance. I know that Proc objects are evaluated when they are called but here we have a block returning a new Array, and not a Proc object.

    can you explain it?
    thx
    Vassilis Vatikiotis, Sep 5, 2011
    #1
    1. Advertising

  2. On 05.09.2011 12:46, Vassilis Vatikiotis wrote:
    > hi all,
    >
    > my question is in the context of sinatra but it's a blocks question really.
    >
    > I have configure block in sinatra (configure blocks in sinatra run
    > only once, upon initialisation). There, I want to load some database
    > records in memory. So I do:
    > configure do
    > set :keys do
    > DB.all.map { |record| record.field }
    > end
    > end
    >
    > Whenever I access the class level variable :keys I get a DB query.
    > Whereas if, inside that configure block, I do:
    >
    > keys = DB.all.map { |record| record.field }
    > set :keys, keys
    >
    > there are no DB queries, I can even stop the database daemon and my app will go on.
    >
    > Now I'm *almost* certain that it's not a sinatra issue but my ruby
    > block ignorance. I know that Proc objects are evaluated when they are
    > called but here we have a block returning a new Array, and not a Proc
    > object.
    >
    > can you explain it?
    > thx


    I don't know Sinatra (apart from Frank, of course) but the reason must
    either be in DB.all's or in set's behavior. To debug it might be
    helpful to insert something like "$stderr.puts 'called'" inside the
    block so you can see how often the block is invoked.

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Sep 5, 2011
    #2
    1. Advertising

  3. Robert Klemme <> wrote:

    > I don't know Sinatra (apart from Frank, of course) but the reason must
    > either be in DB.all's or in set's behavior. To debug it might be
    > helpful to insert something like "$stderr.puts 'called'" inside the
    > block so you can see how often the block is invoked.


    That's correct. For Sinatra he should have used DB.all.or.nothing.at.all.

    and $when.its.love(there) /= in.between()

    I'm surprised somebody else didn't catch this ;-)
    Fritz Wuehler, Sep 5, 2011
    #3
  4. It's sinatra related after all. set stores the block object and every time :keys is referenced it calls the block.
    sorry for of topic and thx
    Vassilis Vatikiotis, Sep 6, 2011
    #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. Ilias Lazaridis
    Replies:
    2
    Views:
    388
    Ilias Lazaridis
    Apr 24, 2005
  2. matt
    Replies:
    1
    Views:
    254
    George Ogata
    Aug 6, 2004
  3. Ilias Lazaridis
    Replies:
    74
    Views:
    745
    Ilias Lazaridis
    Apr 4, 2005
  4. Ilias Lazaridis
    Replies:
    18
    Views:
    328
    Bill Guindon
    Apr 9, 2005
  5. Roy Smith
    Replies:
    6
    Views:
    157
    Chris Angelico
    Dec 3, 2012
Loading...

Share This Page