#9 ✓resolved
Justin Ossevoort

Store defaults after first request

Reported by Justin Ossevoort | June 23rd, 2009 @ 09:47 AM

Currently the default behaves like a "if no value is set, return the (result of) default". So requesting the same attribute,that has no value, multiple times will call the default block multiple times. I know this can be easily worked around by assigning as part of the default body's block, but I think it should logically be the default (or otherwise better documented).

Consider:

class Foo < Doodle
  @@serial = 0
  has :uid do
     default{ @@serial += 1 }
  end
end

x = Foo.new
puts x.uid   # -> 1
puts x.uid   # -> 2

Not exactly what one expects.

Comments and changes to this ticket

  • Justin Ossevoort

    Justin Ossevoort July 7th, 2009 @ 01:14 PM

    Oh, and here is the way to currently work around this:

    class Foo < Doodle
      @@serial = 0
      has :uid do
         default{ @uid = @@serial += 1 }
      end
    end
    
    x = Foo.new
    puts x.uid   # -> 1
    puts x.uid   # -> 1
    
  • Sean O'Halpin

    Sean O'Halpin October 11th, 2009 @ 02:29 AM

    • State changed from “new” to “resolved”

    Apologies for the long delay in replying.

    For your use case, I would use #init rather than #default. Something like this:

    require 'doodle'
    
    class Foo < Doodle
      counter = 0
      has :uid do
        init { counter += 1 }
      end
    end
    
    bar = Foo.new
    bar.uid                         # => 1
    bar.uid                         # => 1
    Foo.new.uid                     # => 2
    

    As you have experienced, the default block is called every time, so it's best not to generate side effects (like updating and using a class variable).

  • Justin Ossevoort

    Justin Ossevoort October 12th, 2009 @ 08:43 AM

    • Tag set to feature

    I see I didn't really state my intentions clearly. What I was looking for was something along the lines of lazy initialization. And neither nor really do that.

    The trick I currently use is:

    class Foo < Doodle
      has :foo do

    default{ @foo = .... }
    
    
    
    
    end end

    But I think it's rather ugly and I can see something like this breaking in some future Doodle release. Also it's probably not what was intended for.

    Probably a more elegant way would be:

    class Foo < Doodle
      has :foo, :lazy do

    init{ ... }
    
    
    
    
    end end

    (or)

    
    
    
    class Bar < Doodle has :bar do
    lazy_init { ... }
    
    
    
    
    end end
  • Justin Ossevoort

    Justin Ossevoort October 21st, 2009 @ 01:45 PM

    My examples were pretty screwed up, here is a cleaned up version with example:

        require 'doodle'
    
        $counter = 0
    
        class Foo < Doodle
           has init_attr do
              init{ $counter += 1 }
           end
    
           has default_attr do
              default{ $counter += 1 }
           end
    
           has lazy_attr, :lazy do
              init{ $counter += 1 }
           end
        end
    
        f = Foo.new
    
        f.init_attr    # => 1
        f.lazy_attr    # => 2
        f.default_attr # => 3
    
        f.init_attr    # => 1
        f.lazy_attr    # => 2
        f.default_attr # => 4
    

    Or as a alternative to init and default:

        require 'doodle'
    
        class Foo < Doodle
            has some_attr do
                lazy_init{ 'bar' }
            end
        end
    

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

This site is for tracking issues for the doodle rubygem.

doodle is a Ruby gem for creating extended attribute accessors with defaults, conversions and validations.

See http://doodle.rubyforge.org/ for more details.

People watching this ticket

Tags

Pages