On Jun 29, 4:17 pm, "Erwin Abbott" <erwin.abb... / gmail.com> wrote:
> Hi,
>
> The [] method is really handy when you have an object that should
> behave like a hash or array. One thing I find myself wishing I could
> also do is something like
>
> def logins[](date)
>   @events.select{|e| e.action == :login and e.date == date}
> end
>
> There may be a better way to deal with this example, but this is just
> to demonstrate the circumstances where you don't have an array or hash
> called logins, but you'd like to be able to use that [] syntax. One
> way I though about doing it is
>
> def logins
>   EventList.new @events.select{|e| e.action == :login}
> end
>
> class EventList
>   def initialize data
>     @data = data
>   end
>   def [] date
>     @data.select{|e| e.date == date}
>   end
> end
>
> logins[Date.today] # => all logins today from @events
>
> I guess some people might prefer to write a method like
> get_logins(date), but I like this syntax.  It seems reasonable to also
> define []= in EventList to update the original @events. What I'd like
> to know is if there's another way to solve this problem, or if there
> are any simple optimizations (maybe only keep one instance of
> EventList and update its contents with each call to #events).

  def logins
    @_logins ||= Proc.new do |date|
      @events.select{|e| e.action == :login and e.date == date}
    end
  end

However, I feel you are limiting yourself. Try something like this
instead:

  def logins
    @_logins ||= (
      l = @events.select{|e| e.action == :login}
      def l.by_date(date)
        select{|e| e.date == date}
      end
      l
    )
  end

Then you can use:

  logins.by_date(date)

If needed, you could change #logins to lazy evaluate too.

T.