which OO programming style in R will result readable to a Python programmer?

后端 未结 3 1318
再見小時候
再見小時候 2020-12-28 19:49

I\'m author of the logging package on CRAN, I don\'t see myself as an R programmer, so I tried to make it as code-compatible with the Python standard logging package as I co

相关标签:
3条回答
  • 2020-12-28 20:16

    This could be done with the proto package. This supports older versions of R (its been around for years) so you would not have a problem of old vs. new versions of R.

    library(proto)
    library(logging)
    
    Logger. <- proto(
            new = function(this, name)
                this$proto(name = name),
            log = function(this, ...) 
                levellog(..., logger = this$name),
            setLevel = function(this, newLevel) 
                logging::setLevel(newLevel, container = this$name),
            addHandler = function(this, ...)
                logging::addHandler(this, ..., logger = this$name), 
            warn = function(this, ...)
                this$log(loglevels["WARN"], ...),
            error = function(this, ...)
                this$log(loglevels["ERROR"], ...) 
    )
    basicConfig()
    l <- Logger.$new(name = "hierarchic.logger.name")
    l$warn("this may be bad")
    l$error("this definitely is bad")
    

    This gives the output:

    > basicConfig()
    > l <- Logger.$new(name = "hierarchic.logger.name")
    > l$warn("this may be bad")
    2011-02-28 10:17:54 WARNING:hierarchic.logger.name:this may be bad
    > l$error("this definitely is bad")
    2011-02-28 10:17:54 ERROR:hierarchic.logger.name:this definitely is bad
    

    In the above we have merely layered proto on top of logging but it would be possible to turn each logging object into a proto object, i.e. it would be both, since both logging objects and proto objects are R environments. That would get rid of the extra layer.

    See the http://r-proto.googlecode.com for more info.

    0 讨论(0)
  • 2020-12-28 20:18

    Why would you repeat the name? It would be more convenient to pass the log-object directly to the function, ie

    logdebug("test",logger=l)
    # or
    logdebug("test",l)
    

    A bit the way one would use connections in a number of functions. That seems more the R way of doing it I guess.

    0 讨论(0)
  • 2020-12-28 20:39

    Sounds like a job for a reference class ?setRefClass, ?ReferenceClasses

    Logger <- setRefClass("Logger",
                      fields=list(name = "character"),
                      methods=list(
                        log = function(level, ...) 
                              { levellog(level, ..., logger=name) },
                        debug = function(...) { log("DEBUG", ...) },
                        info = function(...) { log("INFO", ...) },
                        warn = function(...) { log("WARN", ...) },
                        error = function(...) { log("ERROR", ...) }
                        ))
    

    and then

    > basicConfig()
    > l <- Logger$new(name="hierarchic.logger.name")
    > l$debug("oops")
    > l$info("oops")
    2011-02-11 11:54:05 NumericLevel(INFO):hierarchic.logger.name:oops
    > l$warn("oops")
    2011-02-11 11:54:11 NumericLevel(WARN):hierarchic.logger.name:oops
    > 
    
    0 讨论(0)
提交回复
热议问题