Is there something in R (either a package or base idiom) that is like an Option as found in Scala and other languages (see tag optional for details). Specifically, I'm looking for the following features some object that can:
signify the absence of a value but easily
hold attributes
return a default value in the face of having no contained value without requiring that the result of the default value be calculated unless it is actually needed
I'm sure there are a lot of other nice characteristics of Options that I haven't fully recognized as I'm relatively new to the idiom. Any answer that can provide more than the above listed features gets bonus points, especially if the additional features can be described well.
I tried writing a poor substitute using an R6 class (below). Anything that works better or is more idiomatically aligned with R would be greatly appreciated.
library(R6)
Option <- R6Class("Option",
public = list(
initialize = function(value=NULL) {
self$value <- value
}
,get = function() {
return(self$value)
}
,set = function(value) {
self$value <- value
return(value)
}
,getOrElse = function(...) {
if(self$isDefined()) {
return(self$value)
} else {
return(eval(...))
}
}
,isDefined = function() {
return(!all(is.null(self$value)) && !all(is.na(self$value)))
}
, value = NULL
)
,private = list()
,active = list()
) #end Option
Example:
bob <- Option$new()
bob$isDefined() == FALSE
bob$getOrElse("a") == "a"
bob$getOrElse({Sys.sleep(2);"b"})=="b"
bob$set(value = "a")
bob$isDefined() == TRUE
bob$getOrElse({Sys.sleep(2);"b"})=="a"
Related
heres the code
var _obj;
if (instance_exists(obj_text)) _obj = obj_txt_queued; else _obj = obj_text;
with (instance_create_layer(0, 0, "text_layer", _obj))
{
msg = argument[0];
if (instance_exists(other)) originInstance = other.id else originInstance = noone;
if (argument_count > 1) background = argument[1]; else background = 1;
}
with (obj_phae)
{ if (state != scr_player_state_lock)
{
lastState = state;
state = scr_player_state_lock;
}
}
[layers](https://i.stack.imgur.com/9u9tD.png)
I tried removing any extra rooms that were not needed and I tried changing the layer name to something else.
I also tried using var instance_create_layer() but that obviously didn't work
I'm a bit confused at this part:
with (instance_create_layer(0, 0, "text_layer", _obj))
Especially the with(), as that function will go through every object in the room if it sees an object within the parameter, since you suggested to create a new object with it, I'm surprised it doesn't create an infinite loop. Maybe it works, I've never tried it myself, but I think there's a more logical way to assign variables from one object to a newly created object.
Assuming you want to use the With() statement to address the variables within the _obj, I think you can manage something similair through this function:
var object = instance_create_layer(0, 0, "text_layer", _obj)
object.msg = argument[0];
object.originInstance = id
if (argument_count > 1) object.background = argument[1]; else object.background = 1;
It's probably a given at this point, but double-check that this part of code can only run if it's in the same room that has a layer called "text_layer"
In the worst case, you may also try out instance_create_depth() and use the build-in depth variable from the object instead of the layer names. Using depth is more flexible, but less organised than layers.
In R, is it possible to create a function that sets a default answer after some defined amount of time for menu (or to create something that works like that)?
My best not-working idea is to try using {future}.
Example
library(future)
plan(multisession(workers = 2))
zero_after_s <- function(s) Sys.sleep(s)
zero_after_t_menu <- function(
choices, graphics = FALSE, title = NULL, t = 0
) {
if (t == 0) {
menu(choices, graphics, title)
} else {
time_passed <- future(zero_after_s(t))
while (!resolved(time_passed)) {
return(menu(choices, graphics, title))
}
0
}
}
switch(
zero_after_t_menu(c("List letters", "List LETTERS"), t = 5) + 1,
cat("Nothing done (maybe t seconds passed without answers)\n"),
letters,
LETTERS
)
This cannon work because while will cycle and check its argument only when its body finishes the cycle, i.e., the user has answered to menu. I put this just as a tentative idea of a solution.
I try to call menu from the future (it seems more promising), but I cannot interact with it anymore (obviously), and anyway, it throws an error because menu cannot be used non-interactively :-)
zero_after_t_menu <- function(
choices, graphics = FALSE, title = NULL, t = 0
) {
if (t == 0) {
menu(choices, graphics, title)
} else {
res %<-% future(menu(choices, graphics, title), earlySignal = TRUE)
Sys.sleep(t)
if (resolved(res)) res else 0
}
}
Any ideas or suggestions?
Thank you,
Corrado.
PS: my actual use case is a loop across some (many) files to be (slowly) preprocessed. Under some conditions, I would like to have the opportunity to select what to do. Still, given that it is a very long execution, during nights or not-monitoring time, I would like a safe default selection (e.g., "skip that iteration for the future") to be made automatically to permit the loop to go on without my supervision.
I am interested to see if anyone knows of any better alternative to using conditional count statements in Terraform. By "conditional count statement", I mean a statement where depending a condition like a variable input, count will evaluate to create either 0 or 1 of a resource.
A simple example:
resource "xxxxxxxx" "example" {
count = var.example != null ? 1 : 0
}
Here, the resource will only be created if var.example has a value (is not null), otherwise it will not get created.
Conditional counts usually work ok in practice, but sometimes in more complex uses than the one above it introduces a risk of getting an error during Terraform Plan where it cannot evaluate the result of the count pre-apply.
The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.
Is there any better way to achieve the same effect of creating resources on a conditional basis in Terraform?
Keeping in mind that your terraform config not shown I've used a general example of for_each instead of count.
This is an example of how 2 CNAME records will be created using & in this example terraform modules are used but the same can be done directly on terraform resources.
locals {
cname_records = {
"email" = ["email.domain.net."]
"imap" = ["imap.domain.net."]
}
}
module "aws_route53_record_CNAME" {
source = "app.terraform.io/terraform-cloud-org/route53-record/aws"
version = "1.0.0"
for_each = local.cname_records
records = each.value
name = each.key
zone_id = "YOUR-HOSTED-ZONE-ID"
type = "CNAME"
ttl = "300"
}
It varies by case, but there are some cases where you need to get around this. There is a clever trick, but it seems obtuse in the single item (binary exists or not) case. But in a case where there are actually multiple items, this should help.
This is a completely contrived example but I actually use the method quite a bit. In short, a list of things not known until apply, can be replaced by a list of objects with a key you don't care about. The purpose is that for_each doesn't mind if the value is unknown at plan-time, only if the key is.
Consider the following root module with these four modules.
main.tf
resource "aws_s3_bucket" "this" {
bucket = "h4s-test-bucket"
}
# module "with_count" { # cannot be determined until apply
# source = "./with-count"
# x = aws_s3_bucket.this.id
# }
module "with_for_each_over_item" { # handy workaround
source = "./with-for-each-over-item"
x = aws_s3_bucket.this.id
}
output "with_for_each_over_item" {
value = module.with_for_each_over_item
}
# module "with_for_each_list" { # cannot be determined until apply
# source = "./with-for-each-list"
# x = [aws_s3_bucket.this.id]
# }
module "with_for_each_list_better" { # handy workaround
source = "./with-for-each-list-better"
x = [{ y = aws_s3_bucket.this.id }]
}
output "with_for_each_list_better" {
value = module.with_for_each_list_better
}
module "with_for_each_list_best" { # handier workaround
source = "./with-for-each-list-best"
x = [aws_s3_bucket.this.id]
}
output "with_for_each_list_best" {
value = module.with_for_each_list_best
}
with-count/main.tf (problematic)
variable "x" {
type = string
default = null
}
resource "null_resource" "this" {
count = var.x != null ? 1 : 0
}
output "this" {
value = null_resource.this
}
with-for-each-over-item/main.tf (handy workaround)
variable "x" {
type = string
default = null
}
resource "null_resource" "this" {
for_each = { for i, v in [var.x] : i => v }
}
output "this" {
value = null_resource.this
}
with-for-each-list/main.tf (problematic)
variable "x" {
type = list(string)
default = []
}
resource "null_resource" "this" {
for_each = toset(var.x)
}
output "this" {
value = null_resource.this
}
with-for-each-list-better/main.tf (handy workaround)
variable "x" {
type = list(object({ y = string }))
default = []
}
resource "null_resource" "this" {
for_each = { for i, v in var.x : i => v }
}
output "this" {
value = null_resource.this
}
with-for-each-list-best/main.tf (handiest workaround)
variable "x" {
type = list(string)
default = []
}
resource "null_resource" "this" {
for_each = { for i, v in var.x : i => v }
}
output "this" {
value = null_resource.this
}
Summary
In cases where the variable has a value not known at plan-time, consider using an object where the key is known.
I am asking for help to design a specific R6class and especially to design a run method to would run processes in parallel. Note that all of the code example listed below have not been tested and most likely contain errors. They are just here to help convey how I am thinking about implementing the parallelization of the jobs within my R6Class.
I built a R6class type of object called Input that is a wrapper for a simulation platform. The goal of the class is to ease the writing of individual set of paramers for inputs to the simulation platform. It might look like
input = Input$new()
input$set_parameter_x(...)
input$set_parameter_y(...)
I would like the class to be able to directly run the simulations (with the run method) and do so with a defined number of threads but I am not sure how to best achieve that goal. Note that each process started by run is single threaded. However, I would like that each process started by run can run in parallel of call to method run made from a different instance of the class Input. Something like
input_1$run(executable = "/path/to/executable", maxNbThreads = 4)
input_2$run(executable = "/path/to/executable", maxNbThreads = 4)
input_3$run(executable = "/path/to/executable", maxNbThreads = 4)
input_4$run(executable = "/path/to/executable", maxNbThreads = 4)
would all run in parallel. I don't know much about paralization in R (hence my question) but of course one could do
foreach (input_index = 1:nbInputs) %dopar%
{
require(myPackage)
input = Input$new()
input$set_parameter_x(...)
input$set_parameter_y(...)
input$run(executable = "/path/to/executable", maxNbThreads = 1)
}
instead but I'd wish that the work of parallelizing the processes would be taken into account by the R6class Input and not by the user of this class.
I am thinking about having a vector called runningThreads shared among all instances of the class (a static attribute of the class) using an environment (as explained here). runningThreads would contain the pid's of the currently running jobs. Then, everytime the run method is called, the user would specify the maximal number of threads (maxNbThreads) and, in a while loop it would remove from runningThreads the pid's of jobs that are not active anymore until the length of runningThreads is shorter than the argument maxNbThreads provided to run. run would then run the job and add its pid to runningThreads. The public method run (and private methods hat run would call) might look something like
isAThreadAvailable = function(maxNbThreads)
{
for (thread_index in 1:length(private$runningThreads))
{
thread = private$runningThreads[thread_index]
if (!isThreadRunning(thread))
{
private$runningThreads = private$runningThreads[-thread_index]
}
}
return (length(private$runningThreads) < maxNbThreads)
}
isThreadRunning = function(thread)
{
return (system(paste("kill -0", pid), intern=TRUE))
}
run = function(exec = defaultExecutable, maxNbThreads = 1, sleepTimeInSec = 2)
{
stopifnot(maxNbThreads > 0)
if (maxNbThreads == 1)
{
# Then just run it and wait for it to end
system(paste(exec, paste(private$data, collapse=" ")))
} else
{
while (!isAThreadAvailable(maxNbThreads))
{
Sys.sleep(sleepTimeInSec)
}
newThread = system(paste(exec, paste(private$data, collapse=" "), "&; echo !#"), intern=TRUE)
private$runningThreads = c(private$runningThreads, newThread)
}
}
Does it sound like a good method? There are probably packages that could ease the building my R6class. Would you be so kind as to point me to these packages and maybe show a small example of how it could be used for my run method in my R6Class?
Thanks to the package processx that #HongOoi mentionned in a comment I could implement what I needed. I did in a very similar style as I designed before but the processx package made everything so much easier.
Here is the code for the run method
isAThreadAvailable = function(maxNbThreads)
{
while (private$shared$isOtherProcessCheckingThreads)
{
Sys.sleep(0.001)
}
private$shared$isOtherProcessCheckingThreads = TRUE
thread_index = 1
while (thread_index <= length(private$shared$runningThreads))
{
thread = private$shared$runningThreads[[thread_index]]
if (!thread$is_alive())
{
private$shared$runningThreads = private$shared$runningThreads[-thread_index]
} else
{
thread_index = thread_index + 1
}
}
r = length(private$shared$runningThreads) < maxNbThreads
private$shared$isOtherProcessCheckingThreads = FALSE
return(r)
},
run = function(exec = "SimBit", maxNbThreads = 1, sleepTimeInSec = 1, waitEndOfThread = FALSE)
{
stopifnot(maxNbThreads > 0)
stopifnot(sleepTimeInSec >= 0)
while (!self$isAThreadAvailable(maxNbThreads))
{
Sys.sleep(sleepTimeInSec)
}
newThread = processx::process$new(exec, paste(private$data, collapse=" "))
private$shared$runningThreads = c(private$shared$runningThreads, newThread)
if (waitEndOfThread)
{
while (newThread$is_alive())
{
Sys.sleep(sleepTimeInSec)
}
}
}
The followings are the data to be passed:
get.member.x = function() {
return( list(info.file='x') )
}
get.member.y = function() {
return( list(info.file='y') )
}
I want to use the data in a function. I can pass these data in two ways: 1. Global variables 2. Argument passing.
This is how to pass the data using global variables:
test = function() {
print(get()$info.file)
}
main3 = function(){
get <<- get.member.x
test()
get <<- get.member.y
test()
}
This is how to pass the data using argument passing:
test2 = function(get) {
print(get()$info.file)
}
main2 = function(){
get = get.member.x
test2(get)
get = get.member.y
test2(get)
}
The result of executing the code is here:
> main2()
[1] "x"
[1] "y"
> main3()
[1] "x"
[1] "y"
Now, I wonder if there is any better alternative than these two ways to pass data. Both methods have some disadvantages.
Using global variables is dangerous, because it has side effects on other parts of the code.
Using argument passing is safe but it clutters the function arguments overall the code. In every function where I need these data members, I will have to pass the data as arguments to the caller and called functions.
If there was a way to encapsulate data members in objects, we could overcome these two issue.
Is there any better alternative way of solving this problem? Or do you think that the current way is better than encapsulating the data in objects?
Update:
What do I try to do with this?
My intention is to change the behaviour of functions without changing the code of the functions such that common code is reused. Consider the following code:
test.duplicate = function() {
result = common.fun.1()
result = common.fun.2()
}
common.fun.1 = function() {
# common steps
result = different.fun.1()
# common steps
}
common.fun.2 = function() {
# common steps
result = different.fun.2()
# common steps
}
Above, common.fun.1 and common.fun.2 have a lot of common code. But since one line is different, I have duplicated all the common code.
To prevent the duplication of common code, I can encapsulate the changing part into an external parameter injected into the function:
test.reuse = function() {
result = common.fun()
}
common.fun = function() {
# common steps
result = get()$different.fun()
# common steps
}
Now, in order to change the behaviour we need to change the injected parameter:
get.member.x = function() {
return( list(different.fun=different.fun.1) )
}
get.member.y = function() {
return( list(different.fun=different.fun.2) )
}
get <<- get.member.x
test.reuse()
get <<- get.member.y
test.reuse()
So, we eliminated the duplicated code while changing the behaviour of the function.