[MacRuby-devel] [MacRuby] #744: map on an array delivered by terminal app via scripting bridge gives an immutable error

MacRuby ruby-noreply at macosforge.org
Sat Jun 19 01:04:37 PDT 2010


#744: map on an array delivered by terminal app via scripting bridge gives an
immutable error
----------------------------+-----------------------------------------------
 Reporter:  jazzbox@…       |        Owner:  lsansonetti@…        
     Type:  defect          |       Status:  reopened             
 Priority:  major           |    Milestone:  MacRuby 0.7          
Component:  MacRuby         |   Resolution:                       
 Keywords:                  |  
----------------------------+-----------------------------------------------
Changes (by jazzbox@…):

  * status:  closed => reopened
  * resolution:  invalid =>


Comment:

 Hi Thibault,

 I'm sorry, but I cannot agree! Your Obj-C example is a replacement for
 map! and not for map which should return a new Array and is not allowed to
 modify the original array!

 In the following example map works even with an immutable NSArray

 {{{
 a = NSArray.arrayWithArray [1,2,3]
 p a
 p a.map { |e| e + 10 }
 p a                                # a should be unchanged
 }}}

 and gives correctly

 {{{
 [1, 2, 3]
 [11, 12, 13]
 [1, 2, 3]
 }}}

 If I define my own Array#map my breaking example is working too, see this:

 {{{
 framework 'ScriptingBridge'

 class NSArray # why does Array not work here?
 def my_map &block
   res = []
   self.each { |e| res << block.call(e) }
   res
 end
 end

 term = SBApplication.applicationWithBundleIdentifier('com.apple.terminal')

 p term.windows
 p term.windows.class.ancestors
 p [term.windows.first].map { |w| w.name }
 p NSArray.arrayWithArray(term.windows).map { |w| w.name }
 p term.windows.my_map { |w| w.name }
 }}}

 And last but not least here is my working Obj-C example (although I don't
 like Obj-C very much, but hey, that's my first example with blocks)

 {{{
 #import <Foundation/Foundation.h>
 #import <ScriptingBridge/ScriptingBridge.h>

 int main (int argc, const char * argv[]) {
         NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

         SBApplication *app = [SBApplication
 applicationWithBundleIdentifier:@"com.apple.terminal"];
         SBElementArray *windows = [app windows];

         //NSLog(@"%@", [windows class]);
         NSLog(@"%@", windows);

         NSMutableArray *result = [NSMutableArray arrayWithCapacity:
 [windows count]];
         [windows enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL
 *stop) {
                 //NSLog(@"%@", [obj name]);
                [result addObject:[obj name]];
         }];
         NSLog(@"%@", result);

         [pool drain];
         return 0;
 }
 }}}

 BTW, the original example is still working with my version of MacRuby 0.5!

-- 
Ticket URL: <http://www.macruby.org/trac/ticket/744#comment:2>
MacRuby <http://macruby.org/>



More information about the MacRuby-devel mailing list