From: Robert Klemme Date: 2005-06-02T00:35:23+09:00 Subject: Re: Implementing a Read-Only array Gavin Kistner wrote: > On Jun 1, 2005, at 7:49 AM, Brian Schr�der wrote: >> On 01/06/05, Gavin Kistner 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