Ad
  • Custom User Avatar

    Wow I just saw this. Talk about a delayed response. You make a good point about any? having its own cost, however say that @even and @is_even were used so that both methods could be lazy cached. Now someone needs to update @is_even everytime they update @even, and know to do that. For me, the cost of the any? lookup is not worth the complexity or cost of possible side effects caused later on. In the case of ActiveRecord, cached queries are supported so you could just use that instead. You still incur the lookup cost but again you don't have the dependency and possible side effect issues.

    However it would be a very cool extension of this kata's design to have something like this:

    attr_lazy :foos do
      # Build some data relation, e.g. an ActiveRecord::Relation instance.
    end
    
    # this method is dependant on :foos and should be reset if foos is reset
    attr_lazy :foos?, [:foos] do
      foos.any?
    end
    

    The method could even be smart enough to see that a foo? method is dependent on its non-? version method of the same name and thus automatically use a different name (such as @is_foo) - though that might be too magical.

  • Custom User Avatar

    Its not really inconsistent, its just that you can't define both an attr_lazy :even and a attr_lazy :even?. This was by design. Its not a perfect design, but its a practical one. My practice, and most others from what I can tell, is to use @even instead of something like @is_even when setting a variable on a ? method. In the case of supporting both a even and even? method, I can't think of a use case where I would want them both to be lazy evaluated. Normally the even? method would just work off of the even one. For example:

    class Numbers
      attr_lazy :even do
        @numbers.select(&:even)
      end
      
      def even?
        even.any?
      end
    end
    

    If attr_lazy did support both, that would be a bad practice to use it in this case, because now when you set @even, you also need to clear whatever other variable even? is using at the same time.