From: "Mehr, Assaph (Assaph)" Date: 2004-05-05T11:11:13+09:00 Subject: Re: Why no Proc##[]=() ? Why no Proc##replace() ? Sorry to get real-worldy on an academic discussion, but there's a much easier ruby solution: > # Make it so that a Proc can be a valid lvalue: > class Proc; def []=(*a) self[*a] end end > > def trace_array( an_array, msg ) > proc { |*args| > if args.length() == 1 then > p "#{msg}: Read access at pos #{args[0]}" > an_array[args[0]] > elsif args.length() == 2 then > p "#{msg}: Write access at pos #{args[0}" > an_array[args[0]] = args[1] > else > p "#{msg}: Weird access." > an_array[*args[0...-1]] = args[-1] > end > } > end > > def buggy_meth() > a = [1,2,3] > a = trace_array( a, "a in buggy_meth()") if $Debug > ... use a ... > end > > > In this example you can substitute a Proc where an Array was expected. > The Proc is invoked both for read and write accesses to the Array. > It outputs a msg and then performs the required operation on the Array. > > This is a simple debugging tool made possible thanks to an additional > level of indirection. irb(main):001:0> a = [1,2,3] => [1, 2, 3] irb(main):002:0> class << a irb(main):003:1> def []=(idx, val, *args) irb(main):004:2> puts "accessed as #{idx.to_s}, #{val.to_s}, #{args.to_s}" irb(main):005:2> super(idx,val) irb(main):006:2> end irb(main):007:1> end => nil irb(main):010:0> a[0] = 2 accessed as 0, 2, => 2 irb(main):011:0> a => [2, 2, 3] irb(main):012:0> You can always achieve indirection by redefinition. It's easier on the brain. Proc (and method) do not to me make sense as p[1] = x (or m[1] = x). They can only make sense when there's a reciever, i.e. obj.m[1] = x. This then, is simply method chaining: obj.get_m.[]=(1,x). Proc is an anonymous method bound to some reciever, but obeys the same rules.