RObj: Class in the Ruby way

Description Usage Arguments Details Value Author(s) See Also Examples

Description

Functions providing a OOP mechanism (called R-OOP) inspired from the Ruby language. In order to avoid any confusion, each usual terminoly used in OOP will be prepended by "R-". Then, one will say a R-class instead of class, a R-module instead of module, a R-method instead of method, ....

Usage

1
2
3
4

Arguments

name

a (non-empty) character string specifying the name <name> of the R-class or the R-module to define. For the functions RClass and RNew, name is a R-classname of the form: [_Path_$]_RClass_ [< _ParentRClass_] where _RClass_ is the R-classname to define, _Path_ is the (optional) complete name of the R-module containing the new R-class and _ParentRClass_ is the (optional) parent R-classname. For the function RModule, name has a similar form as before except that no parent R-class needs to be provided. The argument name fulfilled in the method RMethod is either a R-class or an object in the R-OOP mechanism.

...

further arguments depending on the call to perform.

Details

Thanks to the concepts of pointer (see ptR class) and binding (see Binding) derived from the notion of environment prvided by the R system, it is possible to mimick the Object-Oriented Programming used in languages like Ruby, Python, .... The functions RClass and RModule allow us to respectively define R-class and R-module. Module in Ruby can be used either as Mixins or as collection of functions and other objects like Class, for example. R-class is an object specifying the common methods related to a same family of objects to be instantied. Inheritance is provided as Ruby does by appending the parent R-class just after the name of the R-class to define. The new R-classname and parent R-classname are separated by the symbol< as in Ruby. Let us underline that all R-classes and R-modules are respectively of class RClass and RModule but also of class Binding. Each R-object as instance of R-Class is also of class Binding. Actually, all the inheritance stuffs is delegated to the class Binding which is mainly an environment.

The concept of instance variable introduced in Ruby is also proposed in the R-OOP mechanism. It differs between the two languages mainly due to the difference in the nature of objects. In Ruby, atomic objects are mainly static when the other objects are mainly dynamic (Array, Hash, ...). In R, most of the objects are intrinsically static but thanks to the notion of environment and the derived notion of pointer (see class ptR), every static objects in R can now be also used as dynamic objects. An instance variable in Ruby is declared and used inside a method by giving a variable name of the form @varname. In the R-OOP mechanism, each R-object is encapsulated a binding and at least the variable self is instantied and refers to the binding of the R-object itself. An instance variable is then provided inside a R-method by specifying self$varname <- ... for static variable and self$.varname <- ... for dynamic variable . In both cases, self$varname returns the content of the instance variable (equivalent in Ruby to @varname).

Value

Nothing is returned except for the function RNew which returns an object of class name. Notice that the function RClass with an existing object as argument returns its class in the R-OOP mechanism.

Author(s)

R. Drouilhet

See Also

Binding, ptR

Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
## Not run: # This is a ruby code
## Not run: module Famous
## Not run:   class Man
## Not run:     include Artist
## Not run:     def initialize(first="James",last="Bond")
## Not run:       @first=first
## Not run:       @last=last
## Not run:     end
## Not run:     def hello
## Not run:       puts "Hello! I am "+@first+" "+@last+"\n"
## Not run:     end
## Not run:   end
## Not run: end
## Not run: jb3 = Famous::Man.new()
## Not run: jb3.hello
## Not run: # the code below tries to mimick it 

## Module Artist used as a Mixin
RModule(Artist,
    sing=function() cat("La! La! La!\n")
)

## Module Famous used as a container
RModule(Famous)

## Class inside the Module Famous 
RClass(Famous$Man,
  include=Artist, 
  initialize=function(first="James",last="Bond") {self$first <- first;self$.last <- last},
  hello=function() cat("Hello! I am ",self$first," ",self$last,".\n",sep="") 
)
 
jb <- RNew(Famous$Man)
jb2 <- RNew(Famous$Man,first="JAMES",last=jb$.last)

jb$hello()  
jb2$hello() 
jb$sing()   # comes from Artis Mixin!

# Notice that, in the initialize function, "first" is static when "last" is dynamic.
jb$first <- "james"   # content of static instance variable updated
jb$last <- "Bond 007" # content of dynamic instance variable updated
jb$hello()   
# as "last" is a dynamic instance variable 
jb2$hello() # jb2$last has been updated at the same time as jb$last

RClass(jb) # class in the R-OOP mechanism
class(jb)  # usual class in the R system 

# Usual generic function applies!
print(jb)  # => print.RObj called
# The RClass Famous$Man becomes the S3 class Famous.Man 
print.Famous.Man <- function(obj) obj$hello()
print(jb)  # => now, print.Famous.Man called

rcqls/CqlsRObj documentation built on May 27, 2019, 3:04 a.m.