2016-06-03 3 views
0

Я пытаюсь написать обертку TclOO вокруг пакета http. Идея состоит в том, чтобы создать объект, передающий аргументы, которые вы обычно переходите на http::geturl, и имеют code, data, ncode и meta методы для возврата тех же данных, что и соответствующие http:: proc. Чтобы избежать большого набора текста, я надавил на следующее:Переменная указана `info vars`, но не может быть доступна

oo::class create myHttp { 
    constructor {url args} { 
    set responses {data code ncode meta} 
    foreach response $responses { 
     oo::objdefine [self object] variable -append m_$response 
     oo::objdefine [self object] method $response {} [subst -nocommands { 
puts stdout [lsort [info vars *]] 
      return [set m_$response] 
     }] 
    } 

    set tok [http::geturl $url {*}$args] 
    foreach response $responses { 
     set m_$response [http::$response $tok] 
    } 

    http::cleanup $tok 
} 

К сожалению, это не работает.

% set h [myHttp new http://www.google.co.uk] 
% $h code 
m_code m_data m_meta m_ncode 
can't read "m_code": no such variable 

Что здесь происходит? Вывод [info vars] предполагает, что существует m_code, но ошибка говорит об этом. Доступ к переменным непосредственно из пространства имен [info object namespace $h] показывает, что все они существуют и имеют ожидаемые значения, но все методы доступа с ошибкой с той же ошибкой.

Есть ли лучший способ «автоматически генерировать» методы и переменные? Я свободно признаю, что я не совсем определился с определением методов, используя oo::objdefine, а не в заявлении oo::class create, и я попытался добавить, полу-беспорядочно, my variable m_$response и variable m_$response операторы в методах $reponse безрезультатно. Я заинтересован в том, чтобы найти здесь subst, как я обычно нашел в более позднем обзоре, что простой list работал бы адекватно и менее непрозрачно.

Для полноты использования я использую Tcl 8.6.4 с использованием дистрибутива ActiveState в Windows 7 и отладки с помощью TkCon.

+0

Обратите внимание, что 'info vars' будет сообщать имена переменных после того, как они были названы командой' variable', даже если они еще не существуют и считаются «никакой такой переменной». –

+0

Это произойдет, если запись существует в соответствующей таблице переменных, но ее содержимое отсутствует в точке чтения (обычно, поскольку это указатель NULL, Tcl сообщает об этом одинаково для большинства вещей, как если бы переменная не была там вообще). –

ответ

2

Я пишу это как

oo::class create myHttp { 
    variable tok 
    constructor {url args} { 
     set tok [http::geturl $url {*}$args] 
     foreach response {data code ncode meta} { 
      oo::objdefine [self] forward $response http::$response $tok 
     } 

    } 
    destructor { 
     http::cleanup $tok 
    } 
} 

, но если вам действительно нужны переменные для какой-то цели, которые, очевидно, не будет работать.

+0

Спасибо, Питер. Это очень трюк. Мне не нужны переменные и я раньше не смотрел подкоманду 'forward'. – nurdglaw

+0

'forward' позволяет вам делать аккуратные вещи. В частности, он решает свою целевую команду в контексте пространства имен экземпляров, поэтому переходы на уровне классов могут использовать информацию, определенную экземпляром. Это позволяет вам делать незаметно-мощные вещи с почти без кода (это то, как я обертываю виджеты Tk, когда я делаю мегавизоры, хотя есть и множество других трюков). –

Смежные вопросы