首页 > 解决方案 > TclOO:类记录器混合

问题描述

请推荐 TclOO 类记录器 mixin/trait。

tcllib 1.19中包含的记录器在用作类记录器时会中断:

#!/usr/bin/env tclsh
package require logger
package require logger::utils
::oo::class create Main {
    variable log
    constructor {} {
        set this_inst [namespace current]
        set this_klaz [info object class $this_inst]
        set log [::logger::init $this_klaz]
        ::logger::utils::applyAppender \
        -appender "console" \
        -appenderArgs {-conversionPattern {%d \[%p\] \[%M\] %m}} \
        -serviceCmd $log
    }
    method invoke {} {
        ${log}::info "hello"
    }
}
set main [Main new]
$main invoke

生产对象命名空间:

2018/05/15 08:54:43 [info] [::oo::Obj12] hello

而不是类/方法命名空间:

2018/05/15 08:54:43 [info] [::Main::invoke] hello

标签: classloggingtclmixins

解决方案


这是loggerUtils.tcl中的一个错误,因为替换不知道 TclOO。如果是这样,它就不会使用调用该方法的对象的名称,而是使用该方法的名称。(它似乎被设计为与 [incr Tcl] 一起使用,它确实命名了您似乎想要的方法。)::logger::utils::createLogProc%M


理想情况下,您将为每个班级设置一次记录器,而不是每个实例一次。下面是你如何做到这一点:

package require logger
package require logger::utils
::oo::class create Main {
    variable log
    self {
        variable log
        method init {} {
            set log [::logger::init [self]]
            ::logger::utils::applyAppender \
                -appender "console" \
                -appenderArgs {-conversionPattern {%d \[%p\] \[%M\] %m}} \
                -serviceCmd $log
        }
        method logger {} {return $log}
    }
    constructor {} {
        set log [[self class] logger]
    }
    method invoke {} {
        ${log}::info "hello"
    }
}
Main init
set main [Main new]
$main invoke

但这并不能修复错误。这实际上是因为它会像这样查找%M替换的值:

    if {[info level] < 2} {
        set method "global"
    } else {
        set method [lindex [info level -1] 0]
    }

而它可能应该做更多这样的事情:

    if {[info level] < 2} {
        set method "global"
    } elseif {[uplevel 1 {namespace which self}] == "::oo::Helpers::self"} {
        set method [uplevel 1 {string cat [self class] "::" [self method]}]
    } else {
        set method [lindex [info level -1] 0]
    }

推荐阅读