Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Class TclOO:类记录器mixin_Class_Logging_Tcl_Mixins - Fatal编程技术网

Class TclOO:类记录器mixin

Class TclOO:类记录器mixin,class,logging,tcl,mixins,Class,Logging,Tcl,Mixins,请推荐TclOO类记录器mixin/trait 当用作类记录器时,记录器包括中断: #!/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

请推荐TclOO类记录器mixin/trait

当用作类记录器时,记录器包括中断:

#!/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
而不是类/方法命名空间:

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

这是
::logger::utils::createLogProc
中的错误,因为
%M
替换不知道TclOO。如果是,则不会使用调用该方法的对象的名称,而是使用该方法的名称。(它似乎是为了与[incr Tcl]配合使用而设计的,而[incr Tcl]确实像您希望的那样命名方法。)


理想情况下,应该为每个类设置一次记录器,而不是为每个实例设置一次记录器。以下是您如何做到这一点:

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]
    }
如果{[info level]<2}{
设置方法“全局”
}否则{
设置方法[lindex[信息级别-1]0]
}
然而,它可能应该做更多类似的事情:

    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]
    }
如果{[info level]<2}{
设置方法“全局”
}elseif{[uplevel1{namespace which self}]==“::oo::Helpers::self”}{
set方法[uplevel 1{string cat[self-class]::“[self-method]}]
}否则{
设置方法[lindex[信息级别-1]0]
}
模式#1:向方法转发器提供命令

混合:

::oo::class create WithLogger {
    self {
        variable klaz_log
        method init_log {} {
             variable klaz_log [::logger::init [self]]
            ::logger::utils::applyAppender ... $klaz_log
        }
        method klaz_log {} {
            return $klaz_log
        }
    }
    method withLogger {} {
        set this_klaz [self class]
        $this_klaz init_log
        set klaz_log [$this_klaz klaz_log]
        {*}"proc log {level args} {tailcall ${klaz_log}::\${level} {*}\$args}"
    }
}
用法:

::oo::class create Main {
    mixin -append WithLogger
    constructor {} {
        my withLogger ; # needs setup
    }
    method invoke {} {
        log info "hello" ; # uses command-to-method forwarder
    }
}

set main [Main new]
$main invoke
输出:

2018/05/16 15:08:59 [info] [::Main::invoke] hello

是的
namespace current
不会生成您在此处期望的信息。我可能需要花一些时间来解释问题是什么,但核心问题是,您想要的信息没有以非TclOO感知记录器想要的方式找到。也许有一个正确的类名称空间访问的示例,以及在
logger.tcl
source中的特定位置来解决这个问题?很好,谢谢。提交罚单: