From: Robert Klemme Date: 2007-07-11T22:19:14+09:00 Subject: Re: Syntax sugar: method[](...) => method(...) On 29.06.2007 22:17, Erwin Abbott 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). It's pretty easy to achieve what you want: irb(main):001:0> class Foo irb(main):002:1> def logins irb(main):003:2> x = %w{a b c} irb(main):004:2> def x.[](a) irb(main):005:3> select {|e| e == a} irb(main):006:3> end irb(main):007:2> x irb(main):008:2> end irb(main):009:1> end => nil irb(main):010:0> f=Foo.new => # irb(main):014:0> f.logins["w"] => [] irb(main):015:0> f.logins["a"] => ["a"] Here's another variant: irb(main):016:0> class Bar irb(main):017:1> def logins irb(main):018:2> x = %w{a b c} irb(main):019:2> lambda {|a| x.select {|e| e == a}} irb(main):020:2> end irb(main):021:1> end => nil irb(main):022:0> b=Bar.new => # irb(main):023:0> b.logins["a"] => ["a"] irb(main):024:0> b.logins["w"] => [] I.e. you just create a proxy object that will handle the [] call. However I am not sure it's a good idea - it's probably better to return the original array or a copy of it. Kind regards robert