Наследование статической функции в [incr Tcl]

Наследование в incr Tcl не работает должным образом. Рассмотрим код ниже.

package require Itcl

::itcl::class Base \
{
public {
    proc function { } { puts "==== Base::function" }
}
}

::itcl::class Derived { inherit Base }

Base::function
Derived::function    ;# FAILS

Последняя строка не работает, поэтому Base::function не наследуется в Derived, хотя Derived наследуется от Base.

Я делаю что-то не так, или incr Tcl предназначен для поведения так?


person Vahagn    schedule 21.01.2011    source источник


Ответы (2)


Читая документы, я не думаю, что процедуры в классе itcl работают так, как вы думаете, они должны:

имя процедуры ?args? ?тело? Объявляет процедуру с именем name. Процедура — это обычная процедура в пространстве имен класса. В отличие от метода, процедура вызывается без обращения к конкретному объекту. Когда тело процедуры будет выполнено, оно будет иметь автоматический доступ только к общим элементам данных. Если указан список аргументов, он устанавливает информацию об использовании для этого процесса. Команду body можно использовать для переопределения тела процедуры, но список аргументов должен соответствовать этой спецификации. В теле другого метода класса или процедуры процедура может быть вызвана, как и любая другая команда, просто используя ее имя. В любом другом контексте пространства имен процедура вызывается с использованием квалифицированного имени, такого как "className::proc". Процедуры в базовом классе, которые переопределены в текущем классе или скрыты другим базовым классом, также могут быть доступны через их полное имя.

Насколько я понимаю, процедура связана со своим классом, на нее можно ссылаться в производном классе, но она в нем не определена. Например, следующие работы:

package require Itcl

::itcl::class Base {
    public {
        proc function { } { puts "==== Base::function" }
    }
}

::itcl::class Derived { 
inherit Base 
    public {

        proc function { } { 
            puts "==== Derived::function"
            return [Base::function] 
        }
    }
}

Base::function
Derived::function    ;# FAILS
person Jackson    schedule 21.01.2011
comment
Цель состоит в том, чтобы [incr Tcl] классы действовали как C++ классы. Кажется, это языковой дефект. - person Vahagn; 21.01.2011
comment
@Vaagn Кажется, это предполагает, что C ++ - единственный верный способ реализации классов. Другие языки OO делают что-то по-другому, сравните, например, C++ и Smalltalk, когда они делают что-то по-разному, в каком из них есть дефект? - person Jackson; 24.01.2011

Процедура, которую вы определили Base::function, является (более или менее) обычной процедурой в пространстве имен Base. Когда вы наследуете в Itcl, вы наследуете только методы, вы не наследуете процессы. В соответствующей заметке вы не можете вызывать процедуру function из экземпляра Base, вы должны вызывать ее как любую обычную процедуру.

itcl::class Base {
  public {
    proc function { } { puts "==== Base::function" }
  }
  public method test {} {
    $this function
  }
  public method test2 {} {
    function
  }
}

Base bb
bb test   ;# yields error: bad option "function"
bb test2  ;# works as expected
person Trey Jackson    schedule 21.01.2011