Re: [R] Method dispatch in S4
Hi Martin, thank you very much for this profound answer! Your added design advice is very helpful, too! For the 'simple example': Sometimes I am still a little overwhelmed from a certain setting in the code and my ideas how I want to handle a process. But I learn from session to session. In future I will also span the lines more than 80 columns. I am used to the indent in my vim editor. I have one further issue: I do know, that you are one of the leading developers of the bioconductor package which uses (as far as I have read) extensively OOP in R. Is there a package you could suggest to me to learn from by reading and understanding the code? Where can I find the source code? Best Simon On Aug 8, 2013, at 10:00 PM, Martin Morgan mtmor...@fhcrc.org wrote: On 08/04/2013 02:13 AM, Simon Zehnder wrote: So, I found a solution: First in the initialize method of class C coerce the C object into a B object. Then call the next method in the list with the B class object. Now, in the initialize method of class B the object is a B object and the respective generateSpec method is called. Then, in the initialize method of C the returned object from callNextMethod has to be written to the C class object in .Object. See the code below. setMethod(initialize, C, function(.Object, value) {.Object@c - value; object - as(.Object, B); object - callNextMethod(object, value); as(.Object, B) - object; .Object - generateSpec(.Object); return(.Object)}) This setting works. I do not know though, if this setting is the usual way such things are done in R OOP. Maybe the whole class design is disadvantageous. If anyone detects a mistaken design, I am very thankful to learn. Hi Simon -- your 'simple' example is pretty complicated, and I didn't really follow it in detail! The code is not formatted for easy reading (e.g., lines spanning no more than 80 columns) and some of it (e.g., generateSpec) might not be necessary to describe the problem you're having. A good strategy is to ensure that 'new' called with no arguments works (there are other solutions, but following this rule has helped me to keep my classes and methods simple). This is not the case for new(A) new(C) The reason for this strategy has to do with the way inheritance is implemented, in particular the coercion from derived to super class. Usually it is better to provide default values for arguments to initialize, and to specify arguments after a '...'. This means that your initialize methods will respects the contract set out in ?initialize, in particular the handling of unnamed arguments: ...: data to include in the new object. Named arguments correspond to slots in the class definition. Unnamed arguments must be objects from classes that this class extends. I might have written initialize,A-method as setMethod(initialize, A, function(.Object, ..., value=numeric()){ .Object - callNextMethod(.Object, ..., a=value) generateSpec(.Object) }) Likely in a subsequent iteration I would have ended up with (using the convention that function names preceded by '.' are not exported) .A - setClass(A, representation(a = numeric, specA = numeric)) .generateSpecA - function(a) { 1 / a } A - function(a=numeric(), ...) { specA - .generateSpecA(a) .A(..., a=a, specA=specA) } setMethod(generateSpec, A, function(object) { .generateSpecA(object@a) }) ensuring that A() returns a valid object and avoiding the definition of an initialize method entirely. Martin Best Simon On Aug 3, 2013, at 9:43 PM, Simon Zehnder simon.zehn...@googlemail.com wrote: setMethod(initialize, C, function(.Object, value) {.Object@c - value; .Object - callNextMethod(.Object, value); .Object - generateSpec(.Object); return(.Object)}) __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793 __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] Method dispatch in S4
Simon: Have a look at the proto package for which there is a vignette. You may find it suitable for your needs and less intimidating. Cheers, Bert On Fri, Aug 9, 2013 at 7:40 AM, Simon Zehnder szehn...@uni-bonn.de wrote: Hi Martin, thank you very much for this profound answer! Your added design advice is very helpful, too! For the 'simple example': Sometimes I am still a little overwhelmed from a certain setting in the code and my ideas how I want to handle a process. But I learn from session to session. In future I will also span the lines more than 80 columns. I am used to the indent in my vim editor. I have one further issue: I do know, that you are one of the leading developers of the bioconductor package which uses (as far as I have read) extensively OOP in R. Is there a package you could suggest to me to learn from by reading and understanding the code? Where can I find the source code? Best Simon On Aug 8, 2013, at 10:00 PM, Martin Morgan mtmor...@fhcrc.org wrote: On 08/04/2013 02:13 AM, Simon Zehnder wrote: So, I found a solution: First in the initialize method of class C coerce the C object into a B object. Then call the next method in the list with the B class object. Now, in the initialize method of class B the object is a B object and the respective generateSpec method is called. Then, in the initialize method of C the returned object from callNextMethod has to be written to the C class object in .Object. See the code below. setMethod(initialize, C, function(.Object, value) {.Object@c - value; object - as(.Object, B); object - callNextMethod(object, value); as(.Object, B) - object; .Object - generateSpec(.Object); return(.Object)}) This setting works. I do not know though, if this setting is the usual way such things are done in R OOP. Maybe the whole class design is disadvantageous. If anyone detects a mistaken design, I am very thankful to learn. Hi Simon -- your 'simple' example is pretty complicated, and I didn't really follow it in detail! The code is not formatted for easy reading (e.g., lines spanning no more than 80 columns) and some of it (e.g., generateSpec) might not be necessary to describe the problem you're having. A good strategy is to ensure that 'new' called with no arguments works (there are other solutions, but following this rule has helped me to keep my classes and methods simple). This is not the case for new(A) new(C) The reason for this strategy has to do with the way inheritance is implemented, in particular the coercion from derived to super class. Usually it is better to provide default values for arguments to initialize, and to specify arguments after a '...'. This means that your initialize methods will respects the contract set out in ?initialize, in particular the handling of unnamed arguments: ...: data to include in the new object. Named arguments correspond to slots in the class definition. Unnamed arguments must be objects from classes that this class extends. I might have written initialize,A-method as setMethod(initialize, A, function(.Object, ..., value=numeric()){ .Object - callNextMethod(.Object, ..., a=value) generateSpec(.Object) }) Likely in a subsequent iteration I would have ended up with (using the convention that function names preceded by '.' are not exported) .A - setClass(A, representation(a = numeric, specA = numeric)) .generateSpecA - function(a) { 1 / a } A - function(a=numeric(), ...) { specA - .generateSpecA(a) .A(..., a=a, specA=specA) } setMethod(generateSpec, A, function(object) { .generateSpecA(object@a) }) ensuring that A() returns a valid object and avoiding the definition of an initialize method entirely. Martin Best Simon On Aug 3, 2013, at 9:43 PM, Simon Zehnder simon.zehn...@googlemail.com wrote: setMethod(initialize, C, function(.Object, value) {.Object@c - value; .Object - callNextMethod(.Object, value); .Object - generateSpec(.Object); return(.Object)}) __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793 __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- Bert Gunter Genentech Nonclinical Biostatistics Internal Contact Info: Phone: 467-7374 Website:
Re: [R] Method dispatch in S4
Hi Bert, thank you very much for your suggestion! I will take a look at it soon! Best Simon On Aug 9, 2013, at 4:45 PM, Bert Gunter gunter.ber...@gene.com wrote: Simon: Have a look at the proto package for which there is a vignette. You may find it suitable for your needs and less intimidating. Cheers, Bert On Fri, Aug 9, 2013 at 7:40 AM, Simon Zehnder szehn...@uni-bonn.de wrote: Hi Martin, thank you very much for this profound answer! Your added design advice is very helpful, too! For the 'simple example': Sometimes I am still a little overwhelmed from a certain setting in the code and my ideas how I want to handle a process. But I learn from session to session. In future I will also span the lines more than 80 columns. I am used to the indent in my vim editor. I have one further issue: I do know, that you are one of the leading developers of the bioconductor package which uses (as far as I have read) extensively OOP in R. Is there a package you could suggest to me to learn from by reading and understanding the code? Where can I find the source code? Best Simon On Aug 8, 2013, at 10:00 PM, Martin Morgan mtmor...@fhcrc.org wrote: On 08/04/2013 02:13 AM, Simon Zehnder wrote: So, I found a solution: First in the initialize method of class C coerce the C object into a B object. Then call the next method in the list with the B class object. Now, in the initialize method of class B the object is a B object and the respective generateSpec method is called. Then, in the initialize method of C the returned object from callNextMethod has to be written to the C class object in .Object. See the code below. setMethod(initialize, C, function(.Object, value) {.Object@c - value; object - as(.Object, B); object - callNextMethod(object, value); as(.Object, B) - object; .Object - generateSpec(.Object); return(.Object)}) This setting works. I do not know though, if this setting is the usual way such things are done in R OOP. Maybe the whole class design is disadvantageous. If anyone detects a mistaken design, I am very thankful to learn. Hi Simon -- your 'simple' example is pretty complicated, and I didn't really follow it in detail! The code is not formatted for easy reading (e.g., lines spanning no more than 80 columns) and some of it (e.g., generateSpec) might not be necessary to describe the problem you're having. A good strategy is to ensure that 'new' called with no arguments works (there are other solutions, but following this rule has helped me to keep my classes and methods simple). This is not the case for new(A) new(C) The reason for this strategy has to do with the way inheritance is implemented, in particular the coercion from derived to super class. Usually it is better to provide default values for arguments to initialize, and to specify arguments after a '...'. This means that your initialize methods will respects the contract set out in ?initialize, in particular the handling of unnamed arguments: ...: data to include in the new object. Named arguments correspond to slots in the class definition. Unnamed arguments must be objects from classes that this class extends. I might have written initialize,A-method as setMethod(initialize, A, function(.Object, ..., value=numeric()){ .Object - callNextMethod(.Object, ..., a=value) generateSpec(.Object) }) Likely in a subsequent iteration I would have ended up with (using the convention that function names preceded by '.' are not exported) .A - setClass(A, representation(a = numeric, specA = numeric)) .generateSpecA - function(a) { 1 / a } A - function(a=numeric(), ...) { specA - .generateSpecA(a) .A(..., a=a, specA=specA) } setMethod(generateSpec, A, function(object) { .generateSpecA(object@a) }) ensuring that A() returns a valid object and avoiding the definition of an initialize method entirely. Martin Best Simon On Aug 3, 2013, at 9:43 PM, Simon Zehnder simon.zehn...@googlemail.com wrote: setMethod(initialize, C, function(.Object, value) {.Object@c - value; .Object - callNextMethod(.Object, value); .Object - generateSpec(.Object); return(.Object)}) __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793 __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented,
Re: [R] Method dispatch in S4
On 08/09/2013 07:45 AM, Bert Gunter wrote: Simon: Have a look at the proto package for which there is a vignette. You may find it suitable for your needs and less intimidating. Won't help much with S4, though! Some answers here http://stackoverflow.com/questions/5437238/which-packages-make-good-use-of-s4-objects including from Bioconductor simple class in EBImage, the advanced IRanges package and the 'toy' StudentGWAS. Martin Cheers, Bert On Fri, Aug 9, 2013 at 7:40 AM, Simon Zehnder szehn...@uni-bonn.de wrote: Hi Martin, thank you very much for this profound answer! Your added design advice is very helpful, too! For the 'simple example': Sometimes I am still a little overwhelmed from a certain setting in the code and my ideas how I want to handle a process. But I learn from session to session. In future I will also span the lines more than 80 columns. I am used to the indent in my vim editor. I have one further issue: I do know, that you are one of the leading developers of the bioconductor package which uses (as far as I have read) extensively OOP in R. Is there a package you could suggest to me to learn from by reading and understanding the code? Where can I find the source code? Best Simon On Aug 8, 2013, at 10:00 PM, Martin Morgan mtmor...@fhcrc.org wrote: On 08/04/2013 02:13 AM, Simon Zehnder wrote: So, I found a solution: First in the initialize method of class C coerce the C object into a B object. Then call the next method in the list with the B class object. Now, in the initialize method of class B the object is a B object and the respective generateSpec method is called. Then, in the initialize method of C the returned object from callNextMethod has to be written to the C class object in .Object. See the code below. setMethod(initialize, C, function(.Object, value) {.Object@c - value; object - as(.Object, B); object - callNextMethod(object, value); as(.Object, B) - object; .Object - generateSpec(.Object); return(.Object)}) This setting works. I do not know though, if this setting is the usual way such things are done in R OOP. Maybe the whole class design is disadvantageous. If anyone detects a mistaken design, I am very thankful to learn. Hi Simon -- your 'simple' example is pretty complicated, and I didn't really follow it in detail! The code is not formatted for easy reading (e.g., lines spanning no more than 80 columns) and some of it (e.g., generateSpec) might not be necessary to describe the problem you're having. A good strategy is to ensure that 'new' called with no arguments works (there are other solutions, but following this rule has helped me to keep my classes and methods simple). This is not the case for new(A) new(C) The reason for this strategy has to do with the way inheritance is implemented, in particular the coercion from derived to super class. Usually it is better to provide default values for arguments to initialize, and to specify arguments after a '...'. This means that your initialize methods will respects the contract set out in ?initialize, in particular the handling of unnamed arguments: ...: data to include in the new object. Named arguments correspond to slots in the class definition. Unnamed arguments must be objects from classes that this class extends. I might have written initialize,A-method as setMethod(initialize, A, function(.Object, ..., value=numeric()){ .Object - callNextMethod(.Object, ..., a=value) generateSpec(.Object) }) Likely in a subsequent iteration I would have ended up with (using the convention that function names preceded by '.' are not exported) .A - setClass(A, representation(a = numeric, specA = numeric)) .generateSpecA - function(a) { 1 / a } A - function(a=numeric(), ...) { specA - .generateSpecA(a) .A(..., a=a, specA=specA) } setMethod(generateSpec, A, function(object) { .generateSpecA(object@a) }) ensuring that A() returns a valid object and avoiding the definition of an initialize method entirely. Martin Best Simon On Aug 3, 2013, at 9:43 PM, Simon Zehnder simon.zehn...@googlemail.com wrote: setMethod(initialize, C, function(.Object, value) {.Object@c - value; .Object - callNextMethod(.Object, value); .Object - generateSpec(.Object); return(.Object)}) __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793 __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide
Re: [R] Method dispatch in S4
Hi Martin, is proto in S3? I will take a look first at the simple package EBImage. Thank you very much for the suggestions! Best Simon On Aug 9, 2013, at 5:01 PM, Martin Morgan mtmor...@fhcrc.org wrote: On 08/09/2013 07:45 AM, Bert Gunter wrote: Simon: Have a look at the proto package for which there is a vignette. You may find it suitable for your needs and less intimidating. Won't help much with S4, though! Some answers here http://stackoverflow.com/questions/5437238/which-packages-make-good-use-of-s4-objects including from Bioconductor simple class in EBImage, the advanced IRanges package and the 'toy' StudentGWAS. Martin Cheers, Bert On Fri, Aug 9, 2013 at 7:40 AM, Simon Zehnder szehn...@uni-bonn.de wrote: Hi Martin, thank you very much for this profound answer! Your added design advice is very helpful, too! For the 'simple example': Sometimes I am still a little overwhelmed from a certain setting in the code and my ideas how I want to handle a process. But I learn from session to session. In future I will also span the lines more than 80 columns. I am used to the indent in my vim editor. I have one further issue: I do know, that you are one of the leading developers of the bioconductor package which uses (as far as I have read) extensively OOP in R. Is there a package you could suggest to me to learn from by reading and understanding the code? Where can I find the source code? Best Simon On Aug 8, 2013, at 10:00 PM, Martin Morgan mtmor...@fhcrc.org wrote: On 08/04/2013 02:13 AM, Simon Zehnder wrote: So, I found a solution: First in the initialize method of class C coerce the C object into a B object. Then call the next method in the list with the B class object. Now, in the initialize method of class B the object is a B object and the respective generateSpec method is called. Then, in the initialize method of C the returned object from callNextMethod has to be written to the C class object in .Object. See the code below. setMethod(initialize, C, function(.Object, value) {.Object@c - value; object - as(.Object, B); object - callNextMethod(object, value); as(.Object, B) - object; .Object - generateSpec(.Object); return(.Object)}) This setting works. I do not know though, if this setting is the usual way such things are done in R OOP. Maybe the whole class design is disadvantageous. If anyone detects a mistaken design, I am very thankful to learn. Hi Simon -- your 'simple' example is pretty complicated, and I didn't really follow it in detail! The code is not formatted for easy reading (e.g., lines spanning no more than 80 columns) and some of it (e.g., generateSpec) might not be necessary to describe the problem you're having. A good strategy is to ensure that 'new' called with no arguments works (there are other solutions, but following this rule has helped me to keep my classes and methods simple). This is not the case for new(A) new(C) The reason for this strategy has to do with the way inheritance is implemented, in particular the coercion from derived to super class. Usually it is better to provide default values for arguments to initialize, and to specify arguments after a '...'. This means that your initialize methods will respects the contract set out in ?initialize, in particular the handling of unnamed arguments: ...: data to include in the new object. Named arguments correspond to slots in the class definition. Unnamed arguments must be objects from classes that this class extends. I might have written initialize,A-method as setMethod(initialize, A, function(.Object, ..., value=numeric()){ .Object - callNextMethod(.Object, ..., a=value) generateSpec(.Object) }) Likely in a subsequent iteration I would have ended up with (using the convention that function names preceded by '.' are not exported) .A - setClass(A, representation(a = numeric, specA = numeric)) .generateSpecA - function(a) { 1 / a } A - function(a=numeric(), ...) { specA - .generateSpecA(a) .A(..., a=a, specA=specA) } setMethod(generateSpec, A, function(object) { .generateSpecA(object@a) }) ensuring that A() returns a valid object and avoiding the definition of an initialize method entirely. Martin Best Simon On Aug 3, 2013, at 9:43 PM, Simon Zehnder simon.zehn...@googlemail.com wrote: setMethod(initialize, C, function(.Object, value) {.Object@c - value; .Object - callNextMethod(.Object, value); .Object - generateSpec(.Object); return(.Object)}) __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- Computational Biology
Re: [R] Method dispatch in S4
Please read the proto vignette before asking further questions about it. It is an alternative to/version of OOP different from S3 and S4. -- Bert On Fri, Aug 9, 2013 at 8:13 AM, Simon Zehnder szehn...@uni-bonn.de wrote: Hi Martin, is proto in S3? I will take a look first at the simple package EBImage. Thank you very much for the suggestions! Best Simon On Aug 9, 2013, at 5:01 PM, Martin Morgan mtmor...@fhcrc.org wrote: On 08/09/2013 07:45 AM, Bert Gunter wrote: Simon: Have a look at the proto package for which there is a vignette. You may find it suitable for your needs and less intimidating. Won't help much with S4, though! Some answers here http://stackoverflow.com/questions/5437238/which-packages-make-good-use-of-s4-objects including from Bioconductor simple class in EBImage, the advanced IRanges package and the 'toy' StudentGWAS. Martin Cheers, Bert On Fri, Aug 9, 2013 at 7:40 AM, Simon Zehnder szehn...@uni-bonn.de wrote: Hi Martin, thank you very much for this profound answer! Your added design advice is very helpful, too! For the 'simple example': Sometimes I am still a little overwhelmed from a certain setting in the code and my ideas how I want to handle a process. But I learn from session to session. In future I will also span the lines more than 80 columns. I am used to the indent in my vim editor. I have one further issue: I do know, that you are one of the leading developers of the bioconductor package which uses (as far as I have read) extensively OOP in R. Is there a package you could suggest to me to learn from by reading and understanding the code? Where can I find the source code? Best Simon On Aug 8, 2013, at 10:00 PM, Martin Morgan mtmor...@fhcrc.org wrote: On 08/04/2013 02:13 AM, Simon Zehnder wrote: So, I found a solution: First in the initialize method of class C coerce the C object into a B object. Then call the next method in the list with the B class object. Now, in the initialize method of class B the object is a B object and the respective generateSpec method is called. Then, in the initialize method of C the returned object from callNextMethod has to be written to the C class object in .Object. See the code below. setMethod(initialize, C, function(.Object, value) {.Object@c - value; object - as(.Object, B); object - callNextMethod(object, value); as(.Object, B) - object; .Object - generateSpec(.Object); return(.Object)}) This setting works. I do not know though, if this setting is the usual way such things are done in R OOP. Maybe the whole class design is disadvantageous. If anyone detects a mistaken design, I am very thankful to learn. Hi Simon -- your 'simple' example is pretty complicated, and I didn't really follow it in detail! The code is not formatted for easy reading (e.g., lines spanning no more than 80 columns) and some of it (e.g., generateSpec) might not be necessary to describe the problem you're having. A good strategy is to ensure that 'new' called with no arguments works (there are other solutions, but following this rule has helped me to keep my classes and methods simple). This is not the case for new(A) new(C) The reason for this strategy has to do with the way inheritance is implemented, in particular the coercion from derived to super class. Usually it is better to provide default values for arguments to initialize, and to specify arguments after a '...'. This means that your initialize methods will respects the contract set out in ?initialize, in particular the handling of unnamed arguments: ...: data to include in the new object. Named arguments correspond to slots in the class definition. Unnamed arguments must be objects from classes that this class extends. I might have written initialize,A-method as setMethod(initialize, A, function(.Object, ..., value=numeric()){ .Object - callNextMethod(.Object, ..., a=value) generateSpec(.Object) }) Likely in a subsequent iteration I would have ended up with (using the convention that function names preceded by '.' are not exported) .A - setClass(A, representation(a = numeric, specA = numeric)) .generateSpecA - function(a) { 1 / a } A - function(a=numeric(), ...) { specA - .generateSpecA(a) .A(..., a=a, specA=specA) } setMethod(generateSpec, A, function(object) { .generateSpecA(object@a) }) ensuring that A() returns a valid object and avoiding the definition of an initialize method entirely. Martin Best Simon On Aug 3, 2013, at 9:43 PM, Simon Zehnder simon.zehn...@googlemail.com wrote: setMethod(initialize, C, function(.Object, value) {.Object@c - value; .Object - callNextMethod(.Object, value); .Object - generateSpec(.Object); return(.Object)}) __ R-help@r-project.org mailing list
Re: [R] Method dispatch in S4
On 08/04/2013 02:13 AM, Simon Zehnder wrote: So, I found a solution: First in the initialize method of class C coerce the C object into a B object. Then call the next method in the list with the B class object. Now, in the initialize method of class B the object is a B object and the respective generateSpec method is called. Then, in the initialize method of C the returned object from callNextMethod has to be written to the C class object in .Object. See the code below. setMethod(initialize, C, function(.Object, value) {.Object@c - value; object - as(.Object, B); object - callNextMethod(object, value); as(.Object, B) - object; .Object - generateSpec(.Object); return(.Object)}) This setting works. I do not know though, if this setting is the usual way such things are done in R OOP. Maybe the whole class design is disadvantageous. If anyone detects a mistaken design, I am very thankful to learn. Hi Simon -- your 'simple' example is pretty complicated, and I didn't really follow it in detail! The code is not formatted for easy reading (e.g., lines spanning no more than 80 columns) and some of it (e.g., generateSpec) might not be necessary to describe the problem you're having. A good strategy is to ensure that 'new' called with no arguments works (there are other solutions, but following this rule has helped me to keep my classes and methods simple). This is not the case for new(A) new(C) The reason for this strategy has to do with the way inheritance is implemented, in particular the coercion from derived to super class. Usually it is better to provide default values for arguments to initialize, and to specify arguments after a '...'. This means that your initialize methods will respects the contract set out in ?initialize, in particular the handling of unnamed arguments: ...: data to include in the new object. Named arguments correspond to slots in the class definition. Unnamed arguments must be objects from classes that this class extends. I might have written initialize,A-method as setMethod(initialize, A, function(.Object, ..., value=numeric()){ .Object - callNextMethod(.Object, ..., a=value) generateSpec(.Object) }) Likely in a subsequent iteration I would have ended up with (using the convention that function names preceded by '.' are not exported) .A - setClass(A, representation(a = numeric, specA = numeric)) .generateSpecA - function(a) { 1 / a } A - function(a=numeric(), ...) { specA - .generateSpecA(a) .A(..., a=a, specA=specA) } setMethod(generateSpec, A, function(object) { .generateSpecA(object@a) }) ensuring that A() returns a valid object and avoiding the definition of an initialize method entirely. Martin Best Simon On Aug 3, 2013, at 9:43 PM, Simon Zehnder simon.zehn...@googlemail.com wrote: setMethod(initialize, C, function(.Object, value) {.Object@c - value; .Object - callNextMethod(.Object, value); .Object - generateSpec(.Object); return(.Object)}) __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793 __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] Method dispatch in S4
So, I found a solution: First in the initialize method of class C coerce the C object into a B object. Then call the next method in the list with the B class object. Now, in the initialize method of class B the object is a B object and the respective generateSpec method is called. Then, in the initialize method of C the returned object from callNextMethod has to be written to the C class object in .Object. See the code below. setMethod(initialize, C, function(.Object, value) {.Object@c - value; object - as(.Object, B); object - callNextMethod(object, value); as(.Object, B) - object; .Object - generateSpec(.Object); return(.Object)}) This setting works. I do not know though, if this setting is the usual way such things are done in R OOP. Maybe the whole class design is disadvantageous. If anyone detects a mistaken design, I am very thankful to learn. Best Simon On Aug 3, 2013, at 9:43 PM, Simon Zehnder simon.zehn...@googlemail.com wrote: setMethod(initialize, C, function(.Object, value) {.Object@c - value; .Object - callNextMethod(.Object, value); .Object - generateSpec(.Object); return(.Object)}) __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
[R] Method dispatch in S4
Dear R-Users and R-Devels, I am struggling with the method dispatch for S4 objects. First I will give a simple example to make clear what the general setting in my project is. Three classes will be build in the example: A is just a simple class. B contains A in a slot and C inherits from B. In addition all classes have a slot called specA, specB, specC that should be computed during initialization by calling the method generateSpec defined for each class A,B,C: ## Define class A## setClass(A, representation(a = numeric, specA = numeric)) setMethod(initialize, A, function(.Object, value){.Object@a - value; .Object - generateSpec(.Object); return(.Object)}) setGeneric(generateSpec, function(object) standardGeneric(generateSpec)) setMethod(generateSpec, A, function(object) {object@specA - 1/object@a; return(object)}) ## Define class B containing A in a slot ## setClass(B, representation(b = numeric, specB = numeric, A = A)) setMethod(initialize, B, function(.Object, value = 0){.Object@b - value; .Object@A - new(A, value = value); .Object - generateSpec(.Object); return(.Object)}) setMethod(generateSpec, B, function(object) {aSpec - object@A@specA; object@specB - 1/aSpec; return(object)}) ## all fine: new(B, value = 2) ## Define class C inheriting from class B ## setClass(C, representation(c = numeric, specC = numeric), contains=c(B)) setMethod(initialize, C, function(.Object, value) {.Object@c - value; .Object - callNextMethod(.Object, value); .Object - generateSpec(.Object); return(.Object)}) setMethod(generateSpec, C, function(object) {bSpec - object@specB; object@specC - 1/bSpec; return(object)}) ## numeric(0) for specB and specC new(C, value = 2) Note, that the generateSpec method of B depends on the specA slot of A, the generateSpec method of class C depends on the specB slot of class B. Note also, that in the initialize method of B one has to give the value argument a default value. When calling the last line of code, specB and specC are numeric(0). As the slot b of the new C class is equal to 2, the initialize method of class B is called but the .Object in the initialize method of class B is an object of class C. And of course in this case method dispatching chooses the generateSpec method of class C - generateSpec for class B gets never called. In general this is exactly what we want, when inheriting classes: dispatching makes OOP programming not only simpler, but actually possible. My question: How can I make this setting work? How can I generate an initialize method for class B that calls ALWAYS the generateSpec method of class B (using as lets me end up in the initialize method of class C with an object of class B as it is only possible to convert a derived object to its base class but not the other way around)? Best Simon __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.