On 01/06/05, Robert Klemme <bob.news / gmx.net> wrote: > Gavin Kistner wrote: > > On Jun 1, 2005, at 7:49 AM, Brian Schröäer wrote: > >> On 01/06/05, Gavin Kistner <gavin / refinery.com> wrote: > >>> class ReadOnlyArray < Array > >>> alias_method :'__ro_<<', :'<<' #:nodoc: > >>> alias_method :__ro_insert, :insert #:nodoc: > >>> alias_method :__ro_delete_at, :delete_at #:nodoc: > >>> affectors = %w| << []= clear concat delete delete_at delete_if > >>> fill flatten! insert map! pack pop push reject! replace reverse! > >>> shift slice! sort! uniq! unshift | > >>> affectors.each{ |name| undef_method name } > >>> end > >> Why not create a proxy class that contains an array and only forwards > >> the reading methods. It seems to me, that this would achieve exactly > >> what you want. > > > > That's an interesting idea. What advantage do you think that would > > offer compared to my implementation above? How would you modify the > > internal representation when necessary? (Perhaps the constructor for > > the proxy class receives the array that it is supposed to wrap?) > > > > One advantage of mine versus the proxy approach would be that by > > actually inheriting from Array, my class supports additional methods > > defined by the user for Array or Enumerable. (If the user has added a > > special Array#my_collect method, my array is extended as well.) > > > > (I think that it's correct that it would not be possible for a custom > > user method to modify the array, if I'm undef'ing all core methods > > for modifying it, yes?) > > require 'delegate' > > class ImmutableArray < DelegateClass(Array) > def []=(*a) raise "Immutable!" end > def <<(*a) raise "Immutable!" end > def push(*a) raise "Immutable!" end > def unshift(*a) raise "Immutable!" end > end > > ?> a = [1,2,3] > => [1, 2, 3] > >> ia = ImmutableArray.new a > => [1, 2, 3] > >> ia << "bust" > RuntimeError: Immutable! > from (irb):5:in `<<' > from (irb):13 > > :-)) > > Kind regards > > robert > > Though this means that you have to override all methods that can change the array. I'd shurely forget something in this case. You forgot e.g. #clear. Therefore I'd propose to explicitly delegate the needed methods for the application because this is easier to control. best regards, Brian -- http://ruby.brian-schroeder.de/ Stringed instrument chords: http://chordlist.brian-schroeder.de/