What is the best practice OR right way to reference class defined variables from within the class functions? - software-design

Let's say we have a class with 3 class variables and function funA which calls another funB, while funB uses all 3 class declared variables.
So my question is should the funB reference variables from it's body, like this (pseudo-code):
class A{
var var1 = ...
var var2 = ...
var var3 = ...
funA(){
funB()
}
funB(){
// lets say we just multiply the values and store a result somewhere
var result = var1 * var2 * var3
...
}
}
or like this:
class A{
var var1 = ...
var var2 = ...
var var3 = ...
funA(){
funB(var1, var2, var3)
}
funB(var1, var2, var3){
// lets say we just multiply the values and store a result somewhere
var result = var1 * var2 * var3
...
}
}
What is the best practice? Is it dependent on the language?
Thanks in advance!

If the second way is no added value, i would prefer the first way.

Related

How can you chain active fields in R6 classes that are field wrappers?

I'm looking at the code example provided in the R6 class documentation here.
This is the class definition:
Person <- R6Class("Person",
private = list(
.age = NA,
.name = NULL
),
active = list(
age = function(value) {
if (missing(value)) {
private$.age
} else {
stop("`$age` is read only", call. = FALSE)
}
},
name = function(value) {
if (missing(value)) {
private$.name
} else {
stopifnot(is.character(value), length(value) == 1)
private$.name <- value
self
}
}
),
public = list(
initialize = function(name, age = NA) {
private$.name <- name
private$.age <- age
}
)
)
The important part is how the age field is wrapped to be read-only, and the name field is wrapped to perform a validation check before making the assignment.
In my own usecase, I'm not interested in the read-only part, but I am implementing the validation logic. So, focus on the active field for name.
I do not understand why they are following the pattern to return self after the call. How can you chain together assignments? Assuming age wasn't read only, how would it look to try to assign age and name in a chain? I've tried a number of ways, and it never seems to work:
p <- Person$new();
p$age <- 10$name <- "Jill" # obviously doesn't work because how can you reference the name field of 10?
(p$age <- 10)$name <- "Jill" # this looks more likely to work but the parens don't help
p$age(10)$name("Jill") # Does not work, you can't invoke active fields as if they were functions.
# other syntax options?
So, the heart of my question is: if you're using active fields in R6 classes to facilitate some type-checking prior to assignment, you can't really chain those operations together, so why does the official documentation show returning self in the field accessors?

Understanding the effect of c( ) on named vectors

Why is:
c(d = 1:3)
equal to a named vector, as:
d1 d2 d3
1 2 3
And where is this behavior documented?
The c help file does say:
## do *not* use
c(ll, d = 1:3) # which is == c(ll, as.list(c(d = 1:3))
but the as.list is superfluous (and the closing parenthesis missing). And I don't think that amounts to documentation of the behavior above.
That's a nice observation which took me to the actual C Code (since c() is a Primitive function). Just sharing my observation from the code.
And in the actual C code do_c() function that does this c() for R and inside that function there's a section dedicated to assign attributes to the output.
/* Build and attach the names attribute for the returned object. */
if (data.ans_nnames && data.ans_length > 0) {
PROTECT(data.ans_names = allocVector(STRSXP, data.ans_length));
data.ans_nnames = 0;
while (args != R_NilValue) {
struct NameData nameData;
nameData.seqno = 0;
nameData.count = 0;
NewExtractNames(CAR(args), R_NilValue, TAG(args), recurse, &data, &nameData);
args = CDR(args);
}
setAttrib(ans, R_NamesSymbol, data.ans_names);
UNPROTECT(1);
}
which tells us NewExtractNames() is the function that specifically create names and exploring that we can find the information that the sequence is created
/* NewExtractNames(v, base, tag, recurse): For c() and unlist().
* On entry, "base" is the naming component we have acquired by
* recursing down from above.
* If we have a list and we are recursing, we append a new tag component
* to the base tag (either by using the list tags, or their offsets),
* and then we do the recursion.
* If we have a vector, we just create the tags for each element. */
So, to your question it doesn't seem to have been documented anywhere that attribute names are generated with a sequence and assigned it to the result.
Hope it helps.
You can modify this behaviour changing use.names parameter:
c(d = 1:3)
d1 d2 d3
1 2 3
c(d = 1:3,use.names=F)
[1] 1 2 3
More details here:
https://www.rdocumentation.org/packages/base/versions/3.4.3/topics/c

Variable/List Component scope in R?

I come from OOP background (C#/Java to be specific) and I really do not understand how R treat the variable from outside the function.
I made this example:
result = list();
result$total = 0;
result$count = 0;
result$something = "abc";
a = 1:10;
b = 10:20;
mapply(function(x, y) {
print(result$something);
# Does not work with either = or <--
result$total <-- result$total + x + y;
result$count <-- result$count + 1;
print(result$count);
}, x = a, y = b);
result$average = result$total / result$count;
print(result$total);
print(result$count);
print(result$average);
Here, clearly result is available to the anonymous function because the program did print "abc" 10 times.
However, the change to its component total and count does not survive. 10 times it prints 1 for the result$count, and the final 3 lines are 0, 0 and NaN.
Why is this happening? What should I do in this case, if I want the function to be able to change the variable value?
Note: in my real case, result is NOT a global variable, but is inside another function, and I will use return (result) from the function.

Function call in R with named parameters - the name is in a variable instead of writing it directly in the function call

Suppose I have this function:
f <- function(a = 0, b = 1) {
...
}
I want to call this function and specify only parameter b:
f(b = 2);
However, instead of writing b directly above, I would like, if possible, to have the parameter name in a variable:
temp = "b";
f(temp = 2);
The above attempt obviously does not work in R. Any way to do this? Thanks!

Evaluating functions from parent function in child function

Say I have a function:
MyFunction=function(x,y,z,thelist){
a = x+3
b = y+4
c = z+2
mylist=thelist
myfunc1=function(form=a) a+2
myfunc2=function(form=b) b+2
myfunc3=function(form=c) c+2
function(...){
.x = as.list(substitute(list(...)))[-1]
CombinedList = lapply(seq_along(mylist), function (y,.x) {
numbercols = length(eval(.x[[1]])(form=eval(formals(eval(.x[[1]]))$form))[[1]])
numbercolsplusone = numbercols+1
elementz = matrix(NA,nrow=length(.x),ncol=numbercolsplusone)
for (i in seq_along(.x)) {
elementz[i,1:numbercols] = eval(.x[[i]])(form=eval(formals(eval(.x[[i]]))$form))[[y]]
elementz[i,numbercolsplusone] = substr(as.character(.x[[i]]),1,nchar(as.character(.x[[i]]))-4)
}
....
Some more calculations....
....
},.x)
return(CombinedList)
}
}
I then choose, say myfunc1 and myfunc2 from the parent function, and call my toyfunction:
try = Myfunction(x,y,z,thelist)(myfunc1,myfunc2)
This is a toyfunction, and my real function is much longer and takes a lot of time to calculate. I guess the problem lies in the for-loop inside the child function - probably my use of eval.
This function takes longer time to calculate then the the other similar function which only differs in that I call all the functions in my parent function before proceeding to the child function, function(...){. And not choose functions like in this toy-example.
Is there some other, quicker way?

Resources