You can subscribe to this list here.
2002 |
Jan
(2) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(3) |
Oct
(3) |
Nov
|
Dec
(2) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(1) |
Feb
(11) |
Mar
(9) |
Apr
(1) |
May
(5) |
Jun
(5) |
Jul
(4) |
Aug
(3) |
Sep
(15) |
Oct
(8) |
Nov
(9) |
Dec
(11) |
2004 |
Jan
(5) |
Feb
(2) |
Mar
(1) |
Apr
(3) |
May
(6) |
Jun
(4) |
Jul
|
Aug
|
Sep
|
Oct
(9) |
Nov
|
Dec
(3) |
2005 |
Jan
(1) |
Feb
(7) |
Mar
(6) |
Apr
(36) |
May
(20) |
Jun
(42) |
Jul
(21) |
Aug
(12) |
Sep
(56) |
Oct
(5) |
Nov
(55) |
Dec
(53) |
2006 |
Jan
(43) |
Feb
(83) |
Mar
(98) |
Apr
(42) |
May
(68) |
Jun
(55) |
Jul
(50) |
Aug
(104) |
Sep
(13) |
Oct
(70) |
Nov
(37) |
Dec
(42) |
2007 |
Jan
(56) |
Feb
(18) |
Mar
(43) |
Apr
(80) |
May
(65) |
Jun
(149) |
Jul
(103) |
Aug
(71) |
Sep
(62) |
Oct
(67) |
Nov
(72) |
Dec
(63) |
2008 |
Jan
(64) |
Feb
(63) |
Mar
(31) |
Apr
(42) |
May
(71) |
Jun
(62) |
Jul
(37) |
Aug
(25) |
Sep
(5) |
Oct
(2) |
Nov
(7) |
Dec
(14) |
2009 |
Jan
(20) |
Feb
(15) |
Mar
(19) |
Apr
(8) |
May
(7) |
Jun
|
Jul
(37) |
Aug
(12) |
Sep
(19) |
Oct
(5) |
Nov
(1) |
Dec
(4) |
2010 |
Jan
(5) |
Feb
(24) |
Mar
(16) |
Apr
(9) |
May
(4) |
Jun
|
Jul
|
Aug
(6) |
Sep
(2) |
Oct
(1) |
Nov
|
Dec
|
2011 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(7) |
Sep
(1) |
Oct
|
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
(6) |
Oct
|
Nov
|
Dec
|
2013 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
(2) |
Nov
(1) |
Dec
|
2014 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(2) |
Aug
(1) |
Sep
(2) |
Oct
|
Nov
(5) |
Dec
|
2016 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
|
May
(1) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2017 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2018 |
Jan
|
Feb
(1) |
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
From: Rupert B. <rup...@fr...> - 2005-11-18 23:00:56
|
OK, with much help from Jonathan, I have got the Apple SyncServices "SimpleStickies" [1] translated and working (partially) in Ruby. The SimpleStickies is much more than a simple tutorial, the resulting program is a complete syncing engine, demo-ed on the 'Note' class which implements Simple Stickies. What I did was simply to : 1) modify the Objective-C 'main' to startup with Ruby : this is just the standard Ruby 'main.m' and 'rb_main.rb' 2) replace the 'Note.h' and 'Note.m' files for the Note class by 'Note.rb' and kvc_wrapper.rb [2] By the way, do not forget to create the following directory : ~/Library/Application Support/SyncExamples where the tutorial stores its persistence cache. What is working : - the program runs and starts, - it will save data to a persistence XML file store (in ~/Library/ Application Support/SyncExamples) - it will sync with Tiger's SyncServices (both read and write) - .Mac syncing works natively once the data has got into the SyncServices engine : you can see the SimpleStickies logo in the .Mac prefderences : exiting to thing that this is carying data generated by Ruby ! What I cannot get to work : - reading from the XML persistence file store : this must due to some issue with archiving/unarchiving. To get the program to work properly, delete file in ~/Library/Application Support/SyncExamples before every launch - I cannot programmatically (from Ruby) add objects to the Notes controller to get them inserted into GUI Any help would be welcome to help resolve these two points. Rupert [1] SimpleStickies tutorial : http://developer.apple.com/ documentation/AppleApplications/Conceptual/SyncServicesTutorial/ index.html [2] Here are the files : Notes.rb : # # Note.rb # SimpleStickies adapted to Ruby # # Created by Rupert Barrow on 06/11/05. # Copyright (c) 2005 La Romane. All rights reserved. # require 'osx/cocoa' require 'osx/coredata' require 'kvc_wrapper' class Note < OSX::NSObject include OSX kvc_wrapper_representation :createDate, :originX, :originY, :width, :hei ght, :color kvc_wrapper_representation :text, :translucent, :floating, :shaded, :pri maryKey ns_overrides 'init', 'dealloc' @_representation = nil @_changed = nil def init self.super_init @_representation = NSMutableDictionary.dictionary self.setValue_forKey(NSDate.date, "createDate") self.setValue_forKey(100, "originX") self.setValue_forKey(100, "originY") self.setValue_forKey(400, "width") self.setValue_forKey(300, "height") self.setValue_forKey(NSColor.yellowColor, "color") attrString = NSAttributedString.alloc.initWithString("My simple sticky.") self.setValue_forKey(NSArchiver.archivedDataWithRootObject (attrString), "text") self end def dealloc super_dealloc end def changed @_changed end self.addRubyMethod_withType("changed".to_sym, "v@:@") def setChanged(v) @_changed = v end self.addRubyMethod_withType("setChanged:".to_sym, "v@:@") def representation @_representation end def description "representation = #{@_representation.description}" end def valueForUndefinedKey(k) @_representation.valueForKey(k) end def setValue_ForUndefinedKey(v, k) @_representation.setValueForKey(v, k) end def initWithCoder(coder) self.super_init if (coder.allowsKeyedCoding?) @_representation = coder.decodeObjectForKey("representation") else @_representation = coder.decodeObject; end return self end def encodeWithCoder(coder) if (coder.allowsKeyedCoding?) coder.encodeObject_forKey(@_representation, "representation") else coder.encodeObject(@_representation); end return end end kvc_wrapper.rb : # # kvc_wrapper.rb # SimpleStickies adapted to Ruby # # Created by Rupert Barrow on 05/11/05. # Copyright (c) 2005 La Romane. All rights reserved. # # add kvc_wrapper module OSX module NSKVCBehaviorAttachment def kvc_wrapper_representation(*keys) keys.each do |key| set_key = "set#{key}" set_key[3..3] = set_key[3..3].upcase class_eval <<- EOE_KVC_WRAPPER_REPRESENTATION,__FILE__,__LINE__+1 def #{key} # self.willAccessValueForKey("#{key}") @_representation.valueForKey("#{key}") # self.didAccessValueForKey("#{key}") end def #{key}=(val) self.willChangeValueForKey("#{key}") @_representation.setValue_forKey(val, "#{key}") self.didChangeValueForKey("#{key}") end def #{set_key}(val); self.#{key}= val; end EOE_KVC_WRAPPER_REPRESENTATION self.addRubyMethod_withType("#{key}".to_sym, "v@:@") self.addRubyMethod_withType("#{set_key}:".to_sym, "v@:@") end end end end |
From: Rupert B. <rup...@fr...> - 2005-11-14 11:23:41
|
Sorry, posted on the wrong list :-) Rup Le 14 nov. 05 =C3=A0 11:59, Jonathan Paisley a =C3=A9crit : > On 14 Nov 2005, at 0:36, Rupert BARROW wrote: > >> Somehow, from a WSDL file describing an object with an attribute =20 >> called 'Id', soap4r has managed to create an object with an extra =20 >> 'id' attribute, different from the Ruby 'id' : >> >> #<MyObject:0x13f9eec @id=3D"an id"> >> >> How do I reach this value ? >> >> I have the same problem with an attribute called 'name' ... > > Don't know much about soap4r... Try on ruby-talk mailing list? > > You could always use obj.instance_variable_get("@id"), but that's =20 > not very satisfactory. > |
From: Jonathan P. <jp...@dc...> - 2005-11-14 10:59:43
|
On 14 Nov 2005, at 0:36, Rupert BARROW wrote: > Somehow, from a WSDL file describing an object with an attribute > called 'Id', soap4r has managed to create an object with an extra > 'id' attribute, different from the Ruby 'id' : > > #<MyObject:0x13f9eec @id="an id"> > > How do I reach this value ? > > I have the same problem with an attribute called 'name' ... Don't know much about soap4r... Try on ruby-talk mailing list? You could always use obj.instance_variable_get("@id"), but that's not very satisfactory. |
From: Jonathan P. <jp...@dc...> - 2005-11-14 10:51:31
|
> Bingo, Eureka ! > I defined @_changed, as well as its setter and getter : > def changed > @_changed > end > def setChanged(v) > @_changed = v > end > Everything seems to be working OK. > Does anyone know why these have to be defined in Ruby, when they do > not in Objective-C ? It's hard to tell how the pieces fit together without seeing all the code. Can you post a ZIP of the whole project? Cheers Jonathan |
From: Rupert B. <rup...@fr...> - 2005-11-14 00:36:27
|
Hi, Somehow, from a WSDL file describing an object with an attribute called 'Id', soap4r has managed to create an object with an extra 'id' attribute, different from the Ruby 'id' : #<MyObject:0x13f9eec @id="an id"> How do I reach this value ? I have the same problem with an attribute called 'name' ... Rup |
From: kimura w. <ki...@us...> - 2005-11-11 16:01:31
|
Hi, Thu, 10 Nov 2005 18:28:55 -0700, Rod Schmidt wrote: >I have some questions about RubyCocoa's support for key value coding >and the new kvc_accessor and kvc_depends_on methods. > >First off, in Objective-C, all objects are already KVC compliant as >long as you follow certain naming conventions. So why do we have a >separate kvc_accessor method instead of just modifiying attr_accessor >to support key value coding? Is it because attr_accessor is built >into Ruby and we needed a different name? > There is only one difference about style of setter methods in a ruby script. We have to write like this with attr_accesor: obj.setValue_forKey(value, "aKey") We can write like this with kvc_accessor: obj.aKey = value When a ruby script do not use setter methods (ex. access from only Cocoa objects), kvc_accessor equals to attr_accessor. -- kimura wataru |
From: Rupert B. <rup...@fr...> - 2005-11-11 14:52:04
|
Le 11 nov. 05 =C3=A0 14:58, Rupert BARROW a =C3=A9crit : > Jonathan, > > Le 11 nov. 05 =C3=A0 12:51, Jonathan Paisley a =C3=A9crit : > >> >> On 11 Nov 2005, at 10:19, Rupert BARROW wrote: >> >>> if ([record valueForKey:@"changed"] =3D=3D @"YES") = // this crashes >> >> This is unrelated to the main issue, but note that comparison =20 >> doesn't make sense. >> >> You need to compare NSStrings with isEqualToString:, or if =20 >> 'changed' is returning a bool/int try something like: >> >> [(NSNumber*)[record valueForKey:@"changed"] boolValue] > > This code is part of the Apple SImpleStickies tutorial. I have not =20 > changed it. <CUT> > I hope that you can find something. Meanwhile, I will tool around, =20 > trying to define wrappers for the "changed" key. Bingo, Eureka ! I defined @_changed, as well as its setter and getter : def changed @_changed end def setChanged(v) @_changed =3D v end Everything seems to be working OK. Does anyone know why these have to be defined in Ruby, when they do =20 not in Objective-C ? Rup |
From: Jonathan P. <jp...@dc...> - 2005-11-11 11:51:12
|
On 11 Nov 2005, at 10:19, Rupert BARROW wrote: > if ([record valueForKey:@"changed"] == @"YES") // this crashes This is unrelated to the main issue, but note that comparison doesn't make sense. You need to compare NSStrings with isEqualToString:, or if 'changed' is returning a bool/int try something like: [(NSNumber*)[record valueForKey:@"changed"] boolValue] Can you email me your project, or come up with a small ruby test script that demonstrates the problem? It's a bit hard to tell what's going on with the fragments of code. Cheers Jonathan |
From: Jonathan P. <jp...@dc...> - 2005-11-11 11:41:16
|
On 11 Nov 2005, at 1:28, Rod Schmidt wrote: > I have some questions about RubyCocoa's support for key value > coding and the new kvc_accessor and kvc_depends_on methods. > > First off, in Objective-C, all objects are already KVC compliant as > long as you follow certain naming conventions. So why do we have a > separate kvc_accessor method instead of just modifiying > attr_accessor to support key value coding? Is it because > attr_accessor is built into Ruby and we needed a different name? KVC in ObjC works by wrapping setter methods with willChangeValue:forKey: didChangeValue:forKey:. It does this by some sneaky overriding of the method pointers in the class definition. The RubyCocoa classes are dynamically generated, and at the moment ObjC methods do not actually exist that correspond to the getter/ setter. Instead, we catch valueForUndefinedKey: and setValue:forUndefinedKey: and pass through to the ruby getter/setter. At this stage, the willChange/didChange stuff is done explicitly. All this is necessary because KVC can't step in and do its sneaky thing because the methods do not exist in objc land. The same thing situation is there for most methods called from objc - the objc forwardInvocation: method is used to pass unknown selectors to ruby. Just in the past week on this mailing list we've been discussing a problem that arises with CoreData, where it requires the real methods to exist in objc land. What I'm not sure of yet is whether creating these methods in the dynamically generated class allows KVC to do the magic on our behalf, or whether it's still necessary to do the willChange/didChange notifications. > Next, what does kvc_depends_on do? I'm guessing it's for Key Value > Observing? If that's the case why don't we just use the addObserver > method in NSObject that is for that purpose? Or is it just a shortcut? kvc_depends_on is just a wrapper for setKeys:triggerChangeNotificationsForDependentKey:, making it a bit more ruby-like. Here's the definition: def kvc_depends_on(keys, *dependencies) dependencies.flatten.each do |dependentKey| setKeys_triggerChangeNotificationsForDependentKey(keys.to_a, dependentKe y) end end > Sorry if these questions have been answered before, but I haven't > seen a description of what these do. Just scattered discussions > with no clear definition. The binding support stuff is new. I know if there's any particular documentation for it, other than the discussion on the mailing lists. Cheers, Jonathan |
From: Rupert B. <rup...@fr...> - 2005-11-11 10:20:19
|
Hi, I'm back to square one with the SimpleStickies tutorial : encoding and decoding seem to be going well, except that I get the following message while syncing : Exception occured while syncing: Note: this class is not key value coding-compliant for the key "changed" The program looks for all the "changed" entity instances to (presumably) sync them. In - (NSArray *)changedObjectsForEntityName:(NSString *)entityName { NSEnumerator *recordEnumerator = [[self valueForKey:[self keyForEntityName:entityName]] objectEnumerator]; id record; NSMutableArray *changedRecords = [NSMutableArray array]; while (record = [recordEnumerator nextObject]) { if ([record valueForKey:@"changed"] == @"YES") // this crashes [changedRecords addObject:record]; } if ([changedRecords count] == 0) return nil; return changedRecords; } the call to '[record valueForKey:@"changed"]' crashes. Now, I wonder if our calls to self.willChangeValueForKey("#{key}") in our definition of the key_wrappers def kvc_wrapper_representation(*keys) keys.each do |key| set_key = "set#{key}" set_key[3..3] = set_key[3..3].upcase class_eval <<- EOE_KVC_WRAPPER_REPRESENTATION,__FILE__,__LINE__+1 def #{key} @_representation.valueForKey("#{key}") end def #{key}=(val) self.willChangeValueForKey("#{key}") # is this working correctly ? @_representation.setValue_forKey(val, "#{key}") self.didChangeValueForKey("#{key}") end def #{set_key}(val); self.#{key}= val; end EOE_KVC_WRAPPER_REPRESENTATION self.addRubyMethod_withType("#{key}".to_sym, "v@:@") self.addRubyMethod_withType("#{set_key}:".to_sym, "v@:@") end end is working. Any ideas ? Should we maybe (re ?)define the "changed" key for Note somewhere, or is this inherited from NSManaged Object ? I once tried to implement inherited entities in an Objective-C EntityModel test, which did not work : of course, 'Entity- Relationship' modelling is an old father of object-modelling, so I am not totally surprised ... Rup |
From: Rod S. <rsc...@xm...> - 2005-11-11 01:29:20
|
I have some questions about RubyCocoa's support for key value coding and the new kvc_accessor and kvc_depends_on methods. First off, in Objective-C, all objects are already KVC compliant as long as you follow certain naming conventions. So why do we have a separate kvc_accessor method instead of just modifiying attr_accessor to support key value coding? Is it because attr_accessor is built into Ruby and we needed a different name? Next, what does kvc_depends_on do? I'm guessing it's for Key Value Observing? If that's the case why don't we just use the addObserver method in NSObject that is for that purpose? Or is it just a shortcut? Sorry if these questions have been answered before, but I haven't seen a description of what these do. Just scattered discussions with no clear definition. Thanks, Rod Schmidt infiniteNIL Software |
From: kimura w. <ki...@us...> - 2005-11-10 14:54:07
|
RubyCocoa 0.4.2 was released! http://rubycocoa.sourceforge.net/ The '.pkg' binary packages are available for Mac OS X 10.4/10.3/10.2. All of framework, library, documents, samples and Xcode/ProjectBuilder templates are contained in the package. These items will be installed into the appropriate place. It is available to start of RubyCocoa programming or use of RubyCocoa application immediately. == Changes from 0.4.1 === new features * support Cocoa Bindings (Mac OS X 10.3 or later) * support Core Data (Mac OS X 10.4) === bug fixes * a ruby object becomes an instance of OSX::OCObject * itunes_albums.rb fails with NSCharacterConversionException * a ruby script with sub-subclass of a Cocoa class crashes == known problems Following problems are not solved at this relaese. * SEGV/SIGBUS occurs sometimes with ruby Thread * warning "NSView not correctly initialized." appears on console at initializing subclass of NSView (Mac OS X 10.3.9 or later) * "irb -r 'osx/cocoa'" crashes (Mac OS X 10.4) == What's RubyCocoa? RubyCocoa is a Mac OS X framework that allows Cocoa programming in the Object-Oriented Scripting Language Ruby. RubyCocoa allows writing a Cocoa application in Ruby. It allows creating and using a Cocoa object in a Ruby script. In Cocoa application, mixture of program written by both Ruby and Objective-C is possible. Some cases using RubyCocoa: * Exploration of a Cocoa object's feature with 'irb' interactively * Prototyping of a Cocoa application * Cocoa application that include good feature of Ruby and Objective-C * Wrapping Mac OS X native GUI for Ruby script -- kimura wataru |
From: Rupert B. <rup...@fr...> - 2005-11-10 09:27:53
|
Of course ! It works. Great. Thanks for your help. I still have a problem with the syncing, which also occurs with the =20 Objective C program. As soon as I have fixed this, I will post the full sample. Cheers, Rup Le 10 nov. 05 =C3=A0 09:49, Jonathan Paisley a =C3=A9crit : > On 10 Nov 2005, at 6:04, Rupert BARROW wrote: > >> def initWithCoder(coder) >> self.super_init >> if (coder.allowsKeyedCoding) >> > [snip] >> However, the program comes up with the following error, which is =20 >> generated within 'encodeWithCoder' : >> Exception occured while syncing: *** -encodeObject:forKey: only =20 >> defined for abstract class. Define -[NSArchiver =20 >> encodeObject:forKey:]! > > It might be this: > > coder.allowsKeyedCoding > > will be returning an int (0 or 1), which are both true in ruby. Try =20= > using > > code.allowsKeyedCoding? > > instead. > > |
From: Jonathan P. <jp...@dc...> - 2005-11-10 08:50:34
|
On 10 Nov 2005, at 6:04, Rupert BARROW wrote: > def initWithCoder(coder) > self.super_init > if (coder.allowsKeyedCoding) > [snip] > However, the program comes up with the following error, which is > generated within 'encodeWithCoder' : > Exception occured while syncing: *** -encodeObject:forKey: only > defined for abstract class. Define -[NSArchiver > encodeObject:forKey:]! It might be this: coder.allowsKeyedCoding will be returning an int (0 or 1), which are both true in ruby. Try using code.allowsKeyedCoding? instead. |
From: Rupert B. <rup...@fr...> - 2005-11-10 06:04:20
|
Le 9 nov. 05 =C3=A0 00:51, Jonathan Paisley a =C3=A9crit : > On 8 Nov 2005, at 21:52, Rupert BARROW wrote: >>> >>> self.addRubyMethod_withType("#{key}".to_sym, =20 >>> "@4@8:12") >>> self.addRubyMethod_withType("#=20 >>> {set_key}:".to_sym, "@4@8:12@16") > >> >> I tried this; here is the result : >> >> 2005-11-08 22:42:32.463 SimpleStickies[1306] KVO autonotifying =20 >> only supports -set<Key>: methods that return void. Autonotifying =20 >> will not be done for invocations of -[Note setText:]. >> >> Same error is produced for each atribute. >> What is the syntax of the second parameter to =20 >> 'addRubyMethod_withType' ? It does not seem to acknowledge that =20 >> 'void' is returned, although the initial @ is preceded by nothing =20 >> (no type). > > The second argument is a type encoding [1] (see also the =20 > objc_method documentation in [2]). It consists of a type code =20 > followed by (I think) some sort of stack offset. The "Special =20 > Considerations" section in [2] indicates that these are ignored, so =20= > you can probably get away with leaving them out. > > The value I gave before for the setter method is incorrect - it =20 > declares an 'id' type return value, when it should be void. Try =20 > using this instead: "v@:@". This means, from left to right, =20 > v=3D"void", @=3D"id self", :=3D"SEL _cmd", @=3D"id value". Notice how = self =20 > and selector must be explicitly mentioned. Thanks, "v@:@" worked well : we are making progress. I am now stuck on encoding problems : the two methods 'initWithCoder=20 (coder)' and 'encodeWithCoder(coder)' of the NSCoding protocol are =20 defined like this : def initWithCoder(coder) self.super_init if (coder.allowsKeyedCoding) @_representation =3D = coder.decodeObjectForKey("representation") else @_representation =3D coder.decodeObject; end return self end =09 def encodeWithCoder(coder) if (coder.allowsKeyedCoding) coder.encodeObject_forKey(@_representation, = "representation") else coder.encodeObject(@_representation); end return end However, the program comes up with the following error, which is =20 generated within 'encodeWithCoder' : Exception occured while syncing: *** -encodeObject:forKey: only =20 defined for abstract class. Define -[NSArchiver encodeObject:forKey:]! Googling for this shows that it is quite a common error when things =20 have not been programmed correctly (eg testing for =20 'allowsKeyedCoding'), but as I have translated the tutorial over from =20= Objective C ... ... either something is wrong in the code of these two methods, above =20= (Objective-C says 'self=3Dsuper.init' in initWithCoder, but Ruby =20 refuses 'self=3Dsuper_init') ... ... or we have another 'Ruby vs. Objective-C' context/visibility =20 problem. I tried adding the following self.addRubyMethod_withType(:initWithCoder, "@:@") self.addRubyMethod_withType(:encodeWithCoder, "v@:@") which changed nothing. Any ideas ? Rup |
From: Jonathan P. <jp...@dc...> - 2005-11-08 23:51:56
|
On 8 Nov 2005, at 21:52, Rupert BARROW wrote: >> >> self.addRubyMethod_withType("#{key}".to_sym, >> "@4@8:12") >> self.addRubyMethod_withType("# >> {set_key}:".to_sym, "@4@8:12@16") > > I tried this; here is the result : > > 2005-11-08 22:42:32.463 SimpleStickies[1306] KVO autonotifying only > supports -set<Key>: methods that return void. Autonotifying will > not be done for invocations of -[Note setText:]. > > Same error is produced for each atribute. > What is the syntax of the second parameter to > 'addRubyMethod_withType' ? It does not seem to acknowledge that > 'void' is returned, although the initial @ is preceded by nothing > (no type). The second argument is a type encoding [1] (see also the objc_method documentation in [2]). It consists of a type code followed by (I think) some sort of stack offset. The "Special Considerations" section in [2] indicates that these are ignored, so you can probably get away with leaving them out. The value I gave before for the setter method is incorrect - it declares an 'id' type return value, when it should be void. Try using this instead: "v@:@". This means, from left to right, v="void", @="id self", :="SEL _cmd", @="id value". Notice how self and selector must be explicitly mentioned. [1] http://developer.apple.com/documentation/Cocoa/Conceptual/ ObjectiveC/RuntimeOverview/chapter_5_section_6.html [2] http://developer.apple.com/documentation/Cocoa/Reference/ ObjCRuntimeRef/ObjCRuntimeRef/chapter_1.4_section_2.html > By the way, why define "#{key}" (without ':') and "# > {set_key}:" (with ':') ? [sorry for silly newbies' questions] Don't worry, it's not obvious. The first argument is the name of the Objective C method to define. A method with no ':' takes no arguments (the getter), whereas the single : indicates that an argument follows it (for the setter, it's the value to set). What we're effectively doing is programmatically making these Objective C class definitions for our Ruby-defined ObjC class: -(id)key; -(void)setKey:(id)value; Cheers, Jonathan |
From: Rupert B. <rup...@fr...> - 2005-11-08 21:53:05
|
Le 7 nov. 05 =C3=A0 21:29, Jonathan Paisley a =C3=A9crit : > It might be possible to resolve the problem, by defining the =20 > methods in question in Objective C land. There is a special =20 > RubyCocoa method to help you do this. Take a look at the =20 > kvc_array_accessor method declared in oc_import.rb. It uses =20 > addRubyMethod_withType to add a real ObjC method that calls through =20= > to a Ruby method. So you'd convert your kvc_wrapper_representation =20 > to look something like (untested): > > def kvc_wrapper_representation(*keys) > keys.each do |key| > set_key =3D "set" + key > set_key[3..3] =3D set_key[3..3].upcase > class_eval <<-=20 > EOE_KVC_WRAPPER_REPRESENTATION,__FILE__,__LINE__+1 > def #{key} > @_representation.valueForKey("#{key}") > end > def #{key}=3D(val) > self.willChangeValueForKey("#{key}") > @_representation.setValue_forKey(val, "#=20 > {key}") > self.didChangeValueForKey("#{key}") > end > def #{set_key}(val); self.#{key}=3D val; end > EOE_KVC_WRAPPER_REPRESENTATION > self.addRubyMethod_withType("#{key}".to_sym, =20 > "@4@8:12") > self.addRubyMethod_withType("#=20 > {set_key}:".to_sym, "@4@8:12@16") > end > end I tried this; here is the result : 2005-11-08 22:42:32.463 SimpleStickies[1306] KVO autonotifying only =20 supports -set<Key>: methods that return void. Autonotifying will not =20= be done for invocations of -[Note setText:]. Same error is produced for each atribute. What is the syntax of the second parameter to =20 'addRubyMethod_withType' ? It does not seem to acknowledge that =20 'void' is returned, although the initial @ is preceded by nothing (no =20= type). By the way, why define "#{key}" (without ':') and "#{set_key}:" (with =20= ':') ? [sorry for silly newbies' questions] > Having thought about this a bit more, it may be cleaner to =20 > 'improve' the implementation of kvc_reader and kvc_writer to define =20= > these methods and call through to the appropriate ruby setter/=20 > getter. Then you'd implement the delegation to @_representation in =20 > a normal ruby accessor. For the moment, I will leave that to the experts :-) > Hope that makes some sense :) Thanks for you help. Rup |
From: Jonathan P. <jp...@dc...> - 2005-11-07 20:29:49
|
On 7 Nov 2005, at 19:00, Rupert BARROW wrote: > 2005-11-07 19:55:36.494 SimpleStickies[782] Exception syncing: > NSUnknownKeyException, reason [<Note 0x651130> takeValue:forKey:]: > attempt to assign value to unknown key: 'primaryKey'. > This class does not have an instance variable of the name > primaryKey or _primaryKey, nor a method of the name setPrimaryKey, > or _setPrimaryKey > > This is strange since dumping the instance_methods of Note shows > that all the expected methods are there : > setCreateDate > createDate I think these are ruby-level instance methods - not actually known to Objective C. The Objective C -> ruby bridge is accomplished through the ObjC equivalent of Ruby's method_missing. > > So, do you think that SyncServices are using some route which is > bypassing our kvc_wrapper mechanism to reach the primaryKey > "attribute" and getter and setter ? I think the problem is that SyncServices is indirectly checking the Objective C class for a method primaryKey or _primaryKey and failing because they don't exist. The key-value-coding support in RubyCocoa is implemented by hooking into the valueForUndefinedKey: method that KVC calls if such a method doesn't exist. It seems that SyncServices is using another route that doesn't use that method. (this is my guess - haven't looked into it further) It might be possible to resolve the problem, by defining the methods in question in Objective C land. There is a special RubyCocoa method to help you do this. Take a look at the kvc_array_accessor method declared in oc_import.rb. It uses addRubyMethod_withType to add a real ObjC method that calls through to a Ruby method. So you'd convert your kvc_wrapper_representation to look something like (untested): def kvc_wrapper_representation(*keys) keys.each do |key| set_key = "set" + key set_key[3..3] = set_key[3..3].upcase class_eval <<- EOE_KVC_WRAPPER_REPRESENTATION,__FILE__,__LINE__+1 def #{key} @_representation.valueForKey("#{key}") end def #{key}=(val) self.willChangeValueForKey("#{key}") @_representation.setValue_forKey(val, "#{key}") self.didChangeValueForKey("#{key}") end def #{set_key}(val); self.#{key}= val; end EOE_KVC_WRAPPER_REPRESENTATION self.addRubyMethod_withType("#{key}".to_sym, "@4@8:12") self.addRubyMethod_withType("# {set_key}:".to_sym, "@4@8:12@16") end end Having thought about this a bit more, it may be cleaner to 'improve' the implementation of kvc_reader and kvc_writer to define these methods and call through to the appropriate ruby setter/getter. Then you'd implement the delegation to @_representation in a normal ruby accessor. Hope that makes some sense :) Jonathan |
From: Rupert B. <rup...@fr...> - 2005-11-07 19:00:39
|
After looking at CoreData, and getting stuck at chapter 4 of the tutorial, I have moved to SyncServices. I picked up the SimpleStickies tutorial, used the complete (step 3) source code of the tutorial to replace the Note Objective C class by a Note.rb : quite easy, I just had to adapt the recent kvc_wrapper suggestion and came up with : # accessor for keys defined in Cocoa, for _representation def kvc_wrapper_representation(*keys) keys.each do |key| class_eval <<-EOE_KVC_WRAPPER_REPRESENTATION,__FILE__,__LINE__+1 def #{key} @_representation.valueForKey("#{key}") end def #{key}=(val) self.willChangeValueForKey("#{key}") @_representation.setValue_forKey(val, "#{key}") self.didChangeValueForKey("#{key}") end EOE_KVC_WRAPPER_REPRESENTATION end end because the Note class takes its stuff from the _representation attribute. I quickly created new setters called setCreateDate, setOriginX etc. from createDate=, originX=, etc. Before these changes, I ran the app in full Objective C, saved a few Notes, and synced them. Switching to the rubified-Notes, the app will not read them to display them : it complains that 2005-11-07 19:55:36.494 SimpleStickies[782] Exception syncing: NSUnknownKeyException, reason [<Note 0x651130> takeValue:forKey:]: attempt to assign value to unknown key: 'primaryKey'. This class does not have an instance variable of the name primaryKey or _primaryKey, nor a method of the name setPrimaryKey, or _setPrimaryKey This is strange since dumping the instance_methods of Note shows that all the expected methods are there : setCreateDate createDate createDate= etc. primaryKey primaryKey= setPrimaryKey etc. So, do you think that SyncServices are using some route which is bypassing our kvc_wrapper mechanism to reach the primaryKey "attribute" and getter and setter ? Rup |
From: kimura w. <ki...@us...> - 2005-11-07 14:34:13
|
Hi, I added some changes to CVS. This changes enables automated wrapping of Key-Value Coding accessors. When you define a subclass of NSManagedObject, RubyCocoa defines wrappers to attributes and relationships from CoreData models. my Employee.rb at chapter 3. ------------- require 'osx/cocoa' require 'osx/coredata' class Employee < OSX::NSManagedObject kvc_depends_on [:lastName, :firstName], :fullNameAndID @@temp_id = 0 def fullNameAndID sprintf('%s, %s (%d)', lastName.to_s, firstName.to_s, employeeID) end ns_overrides :awakeFromInsert def awakeFromInsert @@temp_id += 1 self.employeeID = OSX::NSNumber.numberWithInt(@@temp_id) end end ------------- A new module function OSX::CoreData.define_wrapper() is core of the feature. Fri, 04 Nov 2005 20:21:09 +0900, kimura wataru wrote: >Hi, > >I'm trying this tutorial. > >I think that is possible to define wrappers automatically from >NSManagedObjectModel#entities -> NSEntityDescription, but I do not >know how to implement. > -- kimura wataru |
From: Rupert B. <rup...@fr...> - 2005-11-04 23:30:57
|
Le 5 nov. 05 =C3=A0 00:22, Jonathan Paisley a =C3=A9crit : >> employeeID =3D 123 # not self.employeeID >> puts employeeID >> puts self > >> self.employeeID =3D 123 # using self.employeeID >> puts employeeID >> puts self > > Ah, my fault for getting this wrong in my earlier message. > > Ruby assumes 'employeeID =3D 123' is a local variable assignment. Of course ! Gee, I'm getting tired. I'm moving on to chapter 4 ... Thanks again, Rup |
From: Jonathan P. <jp...@dc...> - 2005-11-04 23:23:15
|
> employeeID = 123 # not self.employeeID > puts employeeID > puts self > self.employeeID = 123 # using self.employeeID > puts employeeID > puts self Ah, my fault for getting this wrong in my earlier message. Ruby assumes 'employeeID = 123' is a local variable assignment. Hence, the 'puts employeeID' simply retrieves the local variable assigned on the preceding line. CoreData or RubyCocoa are never involved. In your second example, the first line directly calls the setter (self.employeeID=) and the second line indirectly calls the getter (self.employeeID) since no local variable with that name (employeeID) has been defined yet. Hope that makes sense. Glad to hear that things are beginning to work. Jonathan |
From: Rupert B. <rup...@fr...> - 2005-11-04 22:58:59
|
Le 4 nov. 05 =C3=A0 22:04, Jonathan Paisley a =C3=A9crit : > On 4 Nov 2005, at 20:53, Rupert BARROW wrote: > > Try replacing kvc_accessor with kvc_wrapper, as defined by Kimura =20 > Wataru in an email earlier today in this thread. Sorry, I'm on a 'digest' mail subscription to the list, so I missed =20 your post, Kimura-San. > This declares the ruby-level accessors in terms of setValue:forKey: =20= > and valueForKey: which should hopefully solve the problem. > > i.e.: > > kvc_wrapper :lastName, :firstName, :employeeID > kvc_depends_on=20 > ([ :lastName, :firstName, :employeeID ], :fullNameAndID) > > def initialize > employeeID =3D @@lastID > ... > end Great, thanks to both of you, things are now working, but not =20 *exactly* as you mention. In my 'awakeFromInsert' method, why does employeeID =3D 123 # not self.employeeID puts employeeID puts self reply '123' for employeeID, but NOT update self : <Employee: 0x520d00> (entity: Employee; id: 0x523ed0 <x-coredata:///=20 Employee/tFC895DBA-B5E8-4764-B296-32FA106D280E> ; data: { department =3D nil; directReports =3D (); employeeID =3D nil; # not updated firstName =3D First; lastName =3D Last; manager =3D nil; salary =3D 0; }) when self.employeeID =3D 123 # using self.employeeID puts employeeID puts self replies '123' for employeeID AND updates CORRECTLY self ? <Employee: 0x520d00> (entity: Employee; id: 0x523ed0 <x-coredata:///=20 Employee/tFC895DBA-B5E8-4764-B296-32FA106D280E> ; data: { department =3D nil; directReports =3D (); employeeID =3D 123; # updated correctly firstName =3D First; lastName =3D Last; manager =3D nil; salary =3D 0; }) Thanks for your help. Being rather newbie on Cocoa/CoreData and =20 RubyCocoa, I do not know whether I am using incorrectly the former or =20= the latter. Cheers, Rup= |
From: Jonathan P. <jp...@dc...> - 2005-11-04 21:05:18
|
On 4 Nov 2005, at 20:53, Rupert BARROW wrote: > > kvc_accessor :lastName, :firstName, :employeeID > kvc_depends_on > ([ :lastName, :firstName, :employeeID ], :fullNameAndID) > > def initialize > rbSetValue_forKey(NSNumber.numberWithInt(@@lastID), > "employeeID") > > I am setting the employeeID correctly (through setValue), but the > value is not 'arriving' in the coredata object. However, it is not > lost, because I re-read from in another method (fullNameAndID) with > the valueForKey method. You're calling rbSetValue... rather than setValue... The rbSetValue method ends up just calling the ruby employeeID= method, which has the effect of setting the instance variable in the ruby class (look at the definition in oc_import.rb to understand more). Try replacing kvc_accessor with kvc_wrapper, as defined by Kimura Wataru in an email earlier today in this thread. This declares the ruby-level accessors in terms of setValue:forKey: and valueForKey: which should hopefully solve the problem. i.e.: kvc_wrapper :lastName, :firstName, :employeeID kvc_depends_on ([ :lastName, :firstName, :employeeID ], :fullNameAndID) def initialize employeeID = @@lastID ... end Also, since this is a Cocoa class, I'm not sure that the initialize method works - I think you have to override init and define it like in a Cocoa class. I'll try and come up with an example later if you think this is a problem. Hope that helps. Jonathan |
From: Rupert B. <rup...@fr...> - 2005-11-04 20:54:19
|
OK, here is the final results of the experiment. With this code ... class Employee < OSX::NSManagedObject include OSX =09 @@lastID =3D 123 kvc_accessor :lastName, :firstName, :employeeID kvc_depends_on([ :lastName, :firstName, :employeeID ], = :fullNameAndID) def initialize rbSetValue_forKey(NSNumber.numberWithInt(@@lastID), = "employeeID") puts "*** = rbSetValue_forKey(NSNumber.numberWithInt(@@lastID), =20 \"employeeID\") : #{rbValueForKey("employeeID")} ***" end def fullNameAndID puts "*** self =3D #{self} ***" puts "*** rbValueForKey(\"employeeID\") =3D = #{rbValueForKey=20 ("employeeID")} ***" end end ... I get the following output ... *** rbSetValue_forKey(NSNumber.numberWithInt(@@lastID), =20 "employeeID") : 123 *** *** self =3D <Employee: 0x557eb0> (entity: Employee; id: 0x55a950 <x-=20 coredata:///Employee/t31E6B1EE-8E9F-4E1A-BA1E-47CA62FEBF3D> ; data: { department =3D nil; directReports =3D (); employeeID =3D nil; firstName =3D First; lastName =3D Last; manager =3D nil; salary =3D 0; }) *** *** rbValueForKey("employeeID") =3D 123 *** I am setting the employeeID correctly (through setValue), but the =20 value is not 'arriving' in the coredata object. However, it is not =20 lost, because I re-read from in another method (fullNameAndID) with =20 the valueForKey method. Any ideas ? Rup Le 4 nov. 05 =C3=A0 21:32, Rupert Barrow a =C3=A9crit : > Jonathan, > > Thanks for answering quickly. > > I removed definition of the @firstName and @lastName attributes, =20 > and it worked.. > > After studying your answer, I noticed the following : > ' kvc_accessor :lastName, :firstName' > creates these methods : > firstName > firstName=3D > lastName > lastName=3D > > If I comment out this code, the methods disappear. When I dump =20 > Employee, I see the "attributes" : > *** Employee =3D <Employee: 0x3ff5b0> (entity: Employee; id: 0x53f370 =20= > <x-coredata:///Employee/tFE462E87-F74A-4826-8487-7C16DBECD891> ; =20 > data: { > department =3D nil; > directReports =3D (); > employeeID =3D nil; > firstName =3D First; > lastName =3D Last; > manager =3D nil; > salary =3D 0; > }) *** > but when I try to access them, the methods are obviously undefined : > 2005-11-04 21:25:56.696 DepartmentAndEmployees[789] Exception =20 > raised during posting of notification. Ignored. exception: =20 > undefined method `lastName' for class `Employee' > > So : > - kvc_depends_on declares and uses one set of accessors > - CoreData relies on another access/update method : through =20 > setValue:forKey: and valueForKey:, as you mentioned. > > Would it not be nice to 'merge' them both, so as not to have to =20 > handle to access/update methods for the same data ? > > Rup > > > Le 4 nov. 05 =C3=A0 00:13, Jonathan Paisley a =C3=A9crit : > >> On 3 Nov 2005, at 21:31, Rupert Barrow wrote: >> >>> class Employee < OSX::NSManagedObject >>> include OSX >>> >>> attr_accessor :firstName >>> attr_accessor :lastName >>> >>> kvc_accessor :lastName, :firstName >>> kvc_depends_on([ :lastName, :firstName], :fullNameAndID) >>> >>> def initialize >>> @firstName =3D "MyFirst" >>> @lastName =3D "MyLast" >>> end >>> >> >> [Let me say first that I've not used Core Data yet, so this is my =20 >> understanding from glancing over the documentation. Please correct =20= >> any misunderstanding!] >> >> Since you're using Core Data, all the data members of the class =20 >> are already managed for you. Therefore, you should not define =20 >> firstName and lastName as accessors, nor should you use ruby =20 >> @firstName/@lastName variables. > |