См. Следующий пример, демонстрирующий перегрузку.
<?php
class A {
public static function newStaticClass()
{
return new static;
}
public static function newSelfClass()
{
return new self;
}
public function newThisClass()
{
return new $this;
}
}
class B extends A
{
public function newParentClass()
{
return new parent;
}
}
$b = new B;
var_dump($b::newStaticClass()); // B
var_dump($b::newSelfClass()); // A because self belongs to "A"
var_dump($b->newThisClass()); // B
var_dump($b->newParentClass()); // A
class C extends B
{
public static function newSelfClass()
{
return new self;
}
}
$c = new C;
var_dump($c::newStaticClass()); // C
var_dump($c::newSelfClass()); // C because self now points to "C" class
var_dump($c->newThisClass()); // C
var_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"
Большую часть времени вы хотите обратиться к текущему классу, поэтому вы используете static
или $this
. Однако бывают случаи, когда вам нужно self
, потому что вы хотите оригинальный класс, независимо от того, что его расширяет. (Очень, Очень редко)
Когда маркетолог из Sun заявил, что Tcl был " Enterprise Ready », разработчики добавили следующую функцию:
$ tclsh
% clock format [clock seconds] -format %Q
Stardate 63473.2
Моя любимая «скрытая или удобная функция» - это то, как цитирование работает в Tcl. Мне нравится использовать фразу « цитирование - это инструмент, а не правило ». Я также люблю говорить: « фигурные скобки нужны только тогда, когда нужны фигурные скобки »
Хотя в большинстве языков есть правила, по которым разделители блоков должны использоваться для определенных вещей (например, в C вы должны использовать {} для обозначения блока), Tcl не такой строгий.
С Tcl вы можете выбрать любые символы в кавычках, чтобы получить нужный эффект. Конечно, есть лучшие практики, но, в конце концов, вы можете выбрать символ цитирования, который лучше всего позволит вам выполнить работу.
Это означает, например, что вы можете определить процедуру разными способами, включая:
proc foo {args} {
.... body here ....
}
proc foo "args" "
.... body here ....
"
proc foo args [some code that returns the body]
. .. и так далее. То же самое касается условных операторов, циклов и всего остального. (для непосвященных фигурные скобки примерно эквивалентны одинарной кавычке оболочки, двойные кавычки подобны двойной кавычке оболочки, а квадратные скобки подобны обратной кавычке оболочки.)
Так вот, многие люди смотрят на это и говорят: ЧТО? но это действительно дает программисту много возможностей. В comp.lang.tcl мы часто получаем вопросы типа «если я сделаю 'this {and $ that}', как мне получить $ that для расширения?». Ответ следует старой шутке «пациент: доктор, мне больно, когда я обращаюсь к этому доктору: не делай этого». То есть, если вам не нравится поведение, которое вы получаете с одним набором разделителей, выберите другой разделитель. Тот факт, что оператор if обычно строится с фигурными скобками, не означает, что он должен быть построен с фигурными скобками.
Это мой любимый «скрытый» особенность Tcl. Это не скрыто - это прямо на чудесно полной, но краткой справочной странице Tcl (n), но разветвления не ясны, пока вы полностью не разберетесь, как работает Tcl.
Другая неочевидная особенность заключается в том, что нераспознанные команды попадают в обработчик с именем «unknown», который вы можете переопределить. Например. чтобы неизвестные команды обрабатывались как выражения для оценки:
$ tclsh
% 2+2
invalid command name "2+2"
% proc unknown args {uplevel 1 [linsert $args 0 expr]}
% 2+2
4
Дополнительные примеры можно найти на странице вики на Радикальной модификации языка
Команда [трассировка] Tcl позволяет вам перехватывать чтение и запись в любую переменную. Это позволяет вам реализовать наблюдателя для любой переменной и добавить автоматическую проверку диапазона произвольной сложности для любой переменной (как если бы вы обращались к переменной через сеттер / геттер). Вы также можете создать автоматически увеличивающиеся переменные, используя эту технику.
proc varlimit_re {re var key op} {
upvar $var v
if { [regexp -- $re $v] <= 0 } {
error "$var out of range"
}
}
trace add variable ::myvar {write} [list varlimit_re {^[A-H]\d{3}-[0-9a-f]+$}]`
Если вы попытаетесь установить myvar для чего-либо, что не соответствует регулярному выражению, вы получите ошибку времени выполнения.
Удобная функция, которая не скрывается, но обычно не очевидна для людей, пришедших с других языков, заключается в том, что вы можете определить свои собственные структуры управления (или даже переопределить существующие, если хотите жить опасно). Примеры есть в Tcl Wiki
Все «ключевые слова» Tcl являются обычными командами Tcl, включая управляющие структуры, такие как [for], [foreach], [while] и т. Д. Это означает, что вы можете расширить язык, написав новые управляющие структуры в чистом Tcl-коде.
Например, структура try / on / trap была реализована в Tcl 8.6a с использованием только кода Tcl. Точно так же tcllib содержит control :: do, структуру управления do / while.
Многие из них стали возможными благодаря командам [upvar] и [uplevel], которые позволяют вам получить доступ к переменным или выполнить код в другом фрейме стека. .
Tcl - такой простой, открытый язык, в нем очень мало скрытых функций. Все это доступно программисту для расширения и адаптации.
ИМХО, самая большая скрытая особенность Tcl - это его C API. Используя это, действительно легко обернуть основную программу или подсистему C и написать графический интерфейс или другие функции на Tcl. Хотя эта функция не является уникальной для Tcl, Tcl был разработан для этого с нуля, и с C API особенно легко работать.
Вторая величайшая скрытая функция - это упаковщик , великий -папочка всех менеджеров геометрии. При этом графический интерфейс может иметь большие окна с удивительно небольшим объемом кода. Важно отметить, что Tcl / Tk управлял геометрией по крайней мере за 10 лет до появления .net.
Третья важная особенность Tcl - это возможность расширять язык через C API или с помощью команд, определенных в Tcl. Не совсем макросы LISP, но тем не менее довольно гибкие.
Хорошо документированный API C также позволил легко интегрировать его в Perl. Мой опыт работы с Tcl / Tk восходит к 1995 году, но примерно в 2000 году я открыл для себя Perl / Tk и никогда не оглядывался назад.
А в последнее время пакеты Tcl и Tkx Perl предоставляют нам современный графический интерфейс. И два вышеупомянутых модуля, хотя и нетривиальные, включают относительно небольшой объем кода, учитывая то, что они позволяют делать вне языковых границ. И это может быть напрямую связано с превосходным API (и, очевидно, мощью Perl).
[имена массивов]
- один из первых вопросов, который задают новички о том, как перебирать массив foreach {key1 key2} {$ list1 $ list2} {...}
- даже если списки имеют разный размер команда rename
может переименовать любую функцию / proc Я думаю, что команда time прекрасна. Это не совсем скрыто, но это не мешает людям спрашивать "