Title: | Types and Features for Object Oriented Programming |
---|---|
Description: | Construct message-passing style objects with types and features. Q7 types uses composition instead of inheritance in creating derived types, allowing definining any code segment as feature and associating any feature to any object. Compared to R6, Q7 is simpler, more flexible, and more friendly. |
Authors: | Siqi Zhang [aut, cre] , Bayer HealthCare [fnd] |
Maintainer: | Siqi Zhang <[email protected]> |
License: | GPL-3 |
Version: | 0.1.0.9000 |
Built: | 2024-11-19 05:56:22 UTC |
Source: | https://github.com/iqis/q7 |
Clone an Instance
## S3 method for class 'Q7instance' clone(inst, deep = TRUE, ...)
## S3 method for class 'Q7instance' clone(inst, deep = TRUE, ...)
inst |
Q7 object instance |
deep |
to copy nested object instances recursively; Boolean |
... |
dot-dot-dot |
Q7 object instance
Type1 <- type(function(num){ print_num <- function(){ base::print(num) } }) myType1 <- Type1(1) myType1$print_num() myType1_clone <- clone(myType1) myType1_clone$print_num()
Type1 <- type(function(num){ print_num <- function(){ base::print(num) } }) myType1 <- Type1(1) myType1$print_num() myType1_clone <- clone(myType1) myType1_clone$print_num()
Used only inside a type definition
extend(prototype)
extend(prototype)
prototype |
Q7type; function |
localized Q7type; function
Type1 <- type(function(arg1){ val1 <- arg1 get_val1 <- function(){ val1 } }, "Type1") Type2 <- type(function(arg1, arg2){ extend(Type1)(arg1) val2 <- arg2 get_val2 <- function(){ val2 } }, "Type2") myType2 <- Type2("foo", "bar") myType2$get_val1() myType2$get_val2()
Type1 <- type(function(arg1){ val1 <- arg1 get_val1 <- function(){ val1 } }, "Type1") Type2 <- type(function(arg1, arg2){ extend(Type1)(arg1) val2 <- arg2 get_val2 <- function(){ val2 } }, "Type2") myType2 <- Type2("foo", "bar") myType2$get_val1() myType2$get_val2()
Create an Object Feature
feature(expr)
feature(expr)
expr |
expression |
a Q7 feature
Type1 <- type(function(num){}) hasMagic <- feature({ change_number <- function(){ num + 1 } }) myType1 <- Type1(1) %>% hasMagic() myType1$change_number() # Use S3 method dispatch for different behaviors hasMagic <- feature_generic(s3 = "hasMagic") hasMagic.Type1 <- feature({ change_number <- function(){ num + 1 } }) hasMagic.Type2 <- feature({ change_number <- function(){ num - 1 } }) Type1 <- type(function(num){}, s3 = "Type1") %>% hasMagic() Type2 <- type(function(num){}, s3 = "Type2") %>% hasMagic() myType1 <- Type1(1) myType1$change_number() myType2 <- Type2(1) myType2$change_number()
Type1 <- type(function(num){}) hasMagic <- feature({ change_number <- function(){ num + 1 } }) myType1 <- Type1(1) %>% hasMagic() myType1$change_number() # Use S3 method dispatch for different behaviors hasMagic <- feature_generic(s3 = "hasMagic") hasMagic.Type1 <- feature({ change_number <- function(){ num + 1 } }) hasMagic.Type2 <- feature({ change_number <- function(){ num - 1 } }) Type1 <- type(function(num){}, s3 = "Type1") %>% hasMagic() Type2 <- type(function(num){}, s3 = "Type2") %>% hasMagic() myType1 <- Type1(1) myType1$change_number() myType2 <- Type2(1) myType2$change_number()
Use this function when you need to create more than one methods
for Q7 types with different S3 classes.
The s3
field and the feature's name should be the same.
feature_generic(s3, ...)
feature_generic(s3, ...)
s3 |
S3 Class of the feature |
... |
dot-dot-dot |
a generic Q7 feature
Implement any Feature for an Object
implement(obj, feat)
implement(obj, feat)
obj |
Q7 object (type or instance) |
feat |
Q7 feature or expression |
Q7 object (type or instance)
Type1 <- type(function(num){}) myType1 <- Type1(1) %>% implement({ change_number <- function(){ num + 1 } }) myType1$change_number()
Type1 <- type(function(num){}) myType1 <- Type1(1) %>% implement({ change_number <- function(){ num + 1 } }) myType1$change_number()
Is it a Q7 Type, Instance or Feature?
is_type(x) is_instance(x) is_feature(x)
is_type(x) is_instance(x) is_feature(x)
x |
object |
Boolean
Build a Q7 Object Instance from a List
list2inst(x, s3 = "default", parent = parent.frame(), ...)
list2inst(x, s3 = "default", parent = parent.frame(), ...)
x |
list |
s3 |
S3 class name of the instance |
parent |
parent environment of the instance |
... |
dot-dot-dot |
Q7 object instance
my_data <- list(a = 1, add_to_a = function(value){ .my$a <- a + value }) myDataObject <- list2inst(my_data) myDataObject$a myDataObject$add_to_a(20) myDataObject$a
my_data <- list(a = 1, add_to_a = function(value){ .my$a <- a + value }) myDataObject <- list2inst(my_data) myDataObject$a myDataObject$add_to_a(20) myDataObject$a
Make a Localized Copy of a Q7 Type or Instance
localize(obj, envir = parent.frame())
localize(obj, envir = parent.frame())
obj |
Q7 type or instance |
envir |
environment |
function
All public and private members of instance 2 will be copied to instance 1, overwriting any of the same names.
merge(inst1, inst2)
merge(inst1, inst2)
inst1 |
instance to move members to |
inst2 |
instance to move members from |
Q7 instance, with environment identity of inst1
and members from both instances.
Screamer <- type(function(words){ scream <- function(){ paste0(paste(words, collapse = " "), "!!!") } }) Whisperer <- type(function(words){ whisper <- function(){ paste0("shhhhhhh.....", paste(words, collapse = " "), "...") } }) p1 <- Screamer("I love you") p1$scream() p2 <- Whisperer("My parents came back") p2$whisper() p1 <- p1 %>% merge(p2) # note the the "word" for both methods became that of p2 p1$whisper() p1$scream()
Screamer <- type(function(words){ scream <- function(){ paste0(paste(words, collapse = " "), "!!!") } }) Whisperer <- type(function(words){ whisper <- function(){ paste0("shhhhhhh.....", paste(words, collapse = " "), "...") } }) p1 <- Screamer("I love you") p1$scream() p2 <- Whisperer("My parents came back") p2$whisper() p1 <- p1 %>% merge(p2) # note the the "word" for both methods became that of p2 p1$whisper() p1$scream()
Create a Q7 Type
type(fn = function() { }, s3 = "Q7default")
type(fn = function() { }, s3 = "Q7default")
fn |
function; becomes the definition of the object |
s3 |
S3 class for the object; necessary when using S3 generic functions |
Q7 type; function
Adder <- type(function(num1, num2){ add_nums <- function(){ num1 + num2 } }) myAdder <- Adder(1, 2) myAdder$add_nums()
Adder <- type(function(num1, num2){ add_nums <- function(){ num1 + num2 } }) myAdder <- Adder(1, 2) myAdder$add_nums()