我们可以在tclOO中定义静态函数吗?

时间:2016-06-21 07:06:56

标签: tcl

在itcl中,可以在允许

的类中创建一个proc
namespace eval ns {set ::ns::i 0}

::itcl::class clsTest { 
    set ::ns::i 0 ; 
    proc i {} {
        return [incr ::ns::i]
    }
}

clsTest::i
1

在tclOO中是否有一些支持?

2 个答案:

答案 0 :(得分:4)

类(通常)是TclOO中的普通对象,因此您可以在类本身上创建实例方法。这是类声明上下文中self的用途,它是一种强大的技术:

oo::class create clsTest {
    self {
        variable i
        method i {} {
            return [incr i]
        }
    }
}

之后,您可以执行以下操作:

clsTest i
# ==> 1
clsTest i
# ==> 2
clsTest i
# ==> 3

请注意,newcreate 实际只是普通的预定义方法(恰好在C中实现),但您可以添加其他任何内容想。当然oo::class继承自oo::object

如果您要使类级别方法也显示为在实例上可调用的方法,那么您只需要欺骗。我并不是真的推荐它,但转发方法可以实现:

oo::class create clsTest {
    self { ... }
    # This is actually the simplest thing that will work, provided you don't [rename] the class.
    # Use the fully-qualified name if the class command isn't global.
    forward i  clsTest i
}

答案 1 :(得分:1)

来自tcloo wiki:http://wiki.tcl.tk/21595

proc ::oo::define::classmethod {name {args ""} {body ""}} {
    # Create the method on the class if
    # the caller gave arguments and body
    set argc [llength [info level 0]]
    if {$argc == 4} {
        uplevel 1 [list self method $name $args $body]
    } elseif {$argc == 3} {
        return -code error "wrong # args: should be \"[lindex [info level 0] 0] name ?args body?\""
    }

    # Get the name of the current class
    set cls [lindex [info level -1] 1]

    # Get its private “my” command
    set my [info object namespace $cls]::my

    # Make the connection by forwarding
    tailcall forward $name  $my $name
}
oo::class create Foo {
    classmethod boo {x} {
        puts "This is [self]::boo with argument x=$x"
    }
}
Foo create bar
bar boo 42
# --> This is ::Foo::boo with argument x=42
Foo boo 7
# --> This is ::Foo::boo with argument x=7