#10 ✓resolved
Justin Ossevoort

Support for 'predicate' and 'clearer' methods

Reported by Justin Ossevoort | June 23rd, 2009 @ 11:29 AM

I used Moose under perl and there they used the concept of 'predicate' and 'clearer' methods (normally something like: has_X and clear_X). A predicate under ruby would simply be a shorthand for instance_variable_defined? and the clearer would be a shorthand for remove_instance_variable.

Especially the clearer would be usefull, for you can imagine the default block doing some expensive lookup (eg. querying a database) to determine the necessary information, which would effectivly be cached. Running the clearer would mean that the next time the value is requested it will be recalculated. These methods would (optionally) supply the user with more information and control over lazy evaluation when this is desired.

Purely a nice to have, but would complement the current doodle features nicely.

Comments and changes to this ticket

  • Sean O'Halpin

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

    • State changed from “new” to “resolved”

    As you have pointed out, #instance_variable_defined? and #remove_instance_variable do exactly what you want.

    However, using them does rely on the underlying implementation of doodle, so I take your point. I really don't like the 'attribute query' methods of ActiveRecord (e.g. foo.name?) - IMHO they just add to the namespace clutter so I prefer two methods that take arguments over creating two more new methods per attribute.

    Doodle already has #assigned?(name). I have just added #clear!(name), so that will be in the next release (real soon now). For example:

    class Foo < Doodle
      has :name
    foo = Foo("Jim")
    foo.assigned?(:name) # => true
    foo.assigned?(:name) # => false
  • Justin Ossevoort

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

    The clearer is great, that really complements the <.assigned?>

    I agree that the ActiveRecord way is ugly for it really conflicts with the way you'd expect boolean attributes to behave.
    I was thinking more along the lines of:

    class Foo < Doodle
      has :foo, :default => 'bar'
    foo = Foo.new
    foo.assigned?(:name) # => false
    foo.has?(:name)      # => true
    foo.foo = 'foobar'
    foo.assigned?(:name) # => true
    foo.has?(:name)      # => true

    Where <.has?> nicely mirrors the declarative form of Doodle.

  • Justin Ossevoort
  • Sean O'Halpin

    Sean O'Halpin October 15th, 2009 @ 12:28 PM

    I like #has?

    obj.has?(name) would be syntactic sugar for
    obj.doodle.attributes.key?(name) where obj can be either a class or an

    I'll include this in the next release (so we'll have #has?, #assigned?
    and #clear!).

    While we're at it, can you think of any other reflections that should
    be exposed at the class or instance level?

  • Justin Ossevoort

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

    I've been mulling over this for some days, but for these cover the really essential introspection needs. The only possibly relevant one that's possibly missing is whether or not something has a default value.

    For this example I use valued? as the property, but I haven't given much thought for a name:

        require 'doodle'
        class Foo
            has simple_attr
            has default_attr do
                default{ 'bar' }
            has init_attr do
                init{ 'bar' }
        f = Foo.new
        f.has?(:simple_attr)       # => true
        f.valued?(:init_attr)      # => false
        f.assigned?(:init_attr)    # => false
        f.has?(:default_attr)      # => true
        f.valued?(:default_attr)   # => true
        f.assigned?(:default_attr) # => false
        f.has?(:init_attr)         # => true
        f.valued?(:init_attr)      # => true
        f.assigned?(:init_attr)    # => true

    The biggest problem with this one is that I haven't come up with a clear scenario for this information (though it clearly conveys information).

  • Justin Ossevoort

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

    oh and the first block should of course have read:

        f.has?(:simple_attr)       # => true
        f.valued?(:simple_attr)    # => false
        f.assigned?(:simple_attr)  # => false

    Clear case of copy/past bug ;-)

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