🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.tcl
14 messages
14 total messages Started by kokoryn Tue, 12 Jul 2005 13:25
Jak odwołać się do nazwy procedury?
#117
Author: kokoryn
Date: Tue, 12 Jul 2005 13:25
33 lines
2007 bytes
witam

Piszę skrypt, w którym tworzę dynamicznie kilka procedur wg pewnego
schematu. Każda taka procedura ma oczywiście inną nazwę i chciałbym
żeby ta nazwa mogła posłużyć jako indeks w globalnej tablicy, gdzie
każda procedura będzie mogła przechowywać jakieś swoje dane. Z grubsza
wygląda to tak:

array set tab {}

proc create_proc {name}\
{
  proc $name {}\
  {
    global tab
    set tab(???) costam
  }
}

W jaki sposób powinienem odwołać się do nazwy procedury w miejscu
oznaczonym "???" tak, aby móc zapisać coś do tablicy pod odpowiednim
indeksem? Wydawało mi się, że polecenie info powinno dawać taką
możliwość, ale z dokumentacji wynika, że nie daje.

Przy okazji chciałem powiedzieć, że jestem trochę zawiedziony tak małą
aktywnością na pl.comp.lang.tcl. Nie spodziewałem się wprawdzie
jakiegoś wielkiego ruchu, ale na pl.comp.lang.c i pl.comp.programming
cały czas przewijają się jakieś dygresje (czasem nawet całe dyskusje)
o Tcl (stąd zresztą dowiedziałem się o tym języku), więc sądziłem, że
ludzie biorący w nich udział będą pisać tutaj, gdy grupa ruszy. Cóż,
mam nadzieję, że z czasem grupa się rozkręci.

pozdrawiam
Re: Jak odwołać się do nazwy procedury?
#118
Author: Derek Kuliński / takeda
Date: Tue, 12 Jul 2005 18:29
37 lines
2749 bytes
On Tue, 12 Jul 2005 15:25:21 +0200, kokoryn wrote:

> W jaki sposób powinienem odwołać się do nazwy procedury w miejscu
> oznaczonym "???" tak, aby móc zapisać coś do tablicy pod odpowiednim
> indeksem? Wydawało mi się, że polecenie info powinno dawać taką
> możliwość, ale z dokumentacji wynika, że nie daje.

Może to zadziała:
proc ctreate_proc {name} {
  proc $name {} "\
    global tab \
    set tab($name) costam \
  "
}

Ja osobiście nie rozumiem po co takie rozwiązania, ale raczej jak bym coś
takiego miał robić to próbowałbym w ten sposób.
    
> Przy okazji chciałem powiedzieć, że jestem trochę zawiedziony tak małą
> aktywnością na pl.comp.lang.tcl. Nie spodziewałem się wprawdzie
> jakiegoś wielkiego ruchu, ale na pl.comp.lang.c i pl.comp.programming
> cały czas przewijają się jakieś dygresje (czasem nawet całe dyskusje)
> o Tcl (stąd zresztą dowiedziałem się o tym języku), więc sądziłem, że
> ludzie biorący w nich udział będą pisać tutaj, gdy grupa ruszy. Cóż,
> mam nadzieję, że z czasem grupa się rozkręci.

Wiesz grupa jest nowa, i raczej dużo osób nie wie. Jeżeli na innej grupie
widzisz, że ktoś dyskutuje o tcl, możesz poinformować że taka grupa
niedawno zostałą stworzona.

Ale jak teraz obserwuję to raczej stopniowo ruch się powiększa, może wolno,
ale widzę coraz więcej postów, więc raczej IMO nie jest źle.

-- 
ダレック
takeda@IRCnet.EFnet, ICQ# 15827691, TLEN: taked4, YahooIM: takeda64
http://eggwiki.takeda.tk - nowa ulepszona strona !!!
Re: Jak odwołać się do nazwy procedury?
#119
Author: kokoryn
Date: Tue, 12 Jul 2005 21:21
43 lines
2845 bytes
On Tue, 12 Jul 2005 11:29:44 -0700, Derek Kuliński / takeda
<d.kulinski@gmail.com> wrote:

>Może to zadziała:
>proc ctreate_proc {name} {
>  proc $name {} "\
>    global tab \
>    set tab($name) costam \
>  "
>}

Jest to jakiś pomysł (przy okazji - znaki "\" nie są tu niezbędne).
Jednak wydaje mi się, że to rozwiązanie byłoby dobre tylko dla tak
trywialnej procedury. Każde odwołanie się do jakiejś zmiennej w ciele
procedury zostałoby rozwinięte w momencie stworzenia procedury i
trzeba byłoby sporo się namęczyć, żeby to obejść, a efekt byłby bardzo
nieelegancki. Jestem przekonany, że istnieje jakiś ładny sposób.

>Ja osobiście nie rozumiem po co takie rozwiązania, ale raczej jak bym coś
>takiego miał robić to próbowałbym w ten sposób.

Jest mi to potrzebne do uzyskania modelu podobnego do tego, jaki jest
stosowany przy tworzeniu widgetów w Tk. Tam każdy widget ma swoją
procedurę - u mnie analogicznie każda procedura obsługuje pewien
"obiekt", którego stan muszę przechowywać pomiędzy kolejnymi
wywołaniami procedury. Mógłbym to zrobić za pomocą zmiennych
globalnych, ale nie chcę zaśmiecać globalnej przestrzeni nazw, więc
pomyślałem, że będę trzymał te dane w jednej globalnej tablicy. Może
to jest wyważanie otwartych drzwi, ale chyba nie - nic mi nie wiadomo
o jakimś odpowiedniku słowa kluczowego static z C++ w Tcl.

>Wiesz grupa jest nowa, i raczej dużo osób nie wie. Jeżeli na innej grupie
>widzisz, że ktoś dyskutuje o tcl, możesz poinformować że taka grupa
>niedawno zostałą stworzona.

Chyba jest to rozsądne rozwiązanie.

>Ale jak teraz obserwuję to raczej stopniowo ruch się powiększa, może wolno,
>ale widzę coraz więcej postów, więc raczej IMO nie jest źle.

Cóż, ja sam byłem dotąd tylko i wyłącznie biernym użytkownikiem
usenetu, ale jak powstała grupa o Tcl, to zdecydowałem się tutaj
pisać, więc chciałbym, żeby coś się tu działo ;).
Re: Jak odwołać się do nazwy procedury?
#120
Author: Derek Kuliński / takeda
Date: Wed, 13 Jul 2005 01:06
42 lines
3421 bytes
On Tue, 12 Jul 2005 23:21:12 +0200, kokoryn wrote:

> Jest to jakiś pomysł (przy okazji - znaki "\" nie są tu niezbędne).
> Jednak wydaje mi się, że to rozwiązanie byłoby dobre tylko dla tak
> trywialnej procedury. Każde odwołanie się do jakiejś zmiennej w ciele
> procedury zostałoby rozwinięte w momencie stworzenia procedury i
> trzeba byłoby sporo się namęczyć, żeby to obejść, a efekt byłby bardzo
> nieelegancki. Jestem przekonany, że istnieje jakiś ładny sposób.

Wątpię, co Ty chcesz robić to coś co samo modyfikujący się kod, a to raczej
rzadko było eleganckie.

>>Ja osobiście nie rozumiem po co takie rozwiązania, ale raczej jak bym coś
>>takiego miał robić to próbowałbym w ten sposób.
> Jest mi to potrzebne do uzyskania modelu podobnego do tego, jaki jest
> stosowany przy tworzeniu widgetów w Tk. Tam każdy widget ma swoją
> procedurę - u mnie analogicznie każda procedura obsługuje pewien
> "obiekt", którego stan muszę przechowywać pomiędzy kolejnymi
> wywołaniami procedury. Mógłbym to zrobić za pomocą zmiennych
> globalnych, ale nie chcę zaśmiecać globalnej przestrzeni nazw, więc
> pomyślałem, że będę trzymał te dane w jednej globalnej tablicy. Może
> to jest wyważanie otwartych drzwi, ale chyba nie - nic mi nie wiadomo
> o jakimś odpowiedniku słowa kluczowego static z C++ w Tcl.

Wiesz, jeszcze nie używałem tych widgetów.

Ale nie możesz np używać namespaces, albo incr tcl (to bodajże obiektowy
tcl, więc powinien mieć coś takiego wbudowane).

>>Ale jak teraz obserwuję to raczej stopniowo ruch się powiększa, może wolno,
>>ale widzę coraz więcej postów, więc raczej IMO nie jest źle.
> Cóż, ja sam byłem dotąd tylko i wyłącznie biernym użytkownikiem
> usenetu, ale jak powstała grupa o Tcl, to zdecydowałem się tutaj
> pisać, więc chciałbym, żeby coś się tu działo ;).

No nie będzie się nic działo jak nikt nie będzie zadawał pytań czy udzielał
odpowiedzi =)

-- 
ダレック
takeda@IRCnet.EFnet, ICQ# 15827691, TLEN: taked4, YahooIM: takeda64
http://eggwiki.takeda.tk - nowa ulepszona strona !!!
Re: Jak odwołać się do nazwy procedury?
#127
Author: Wojciech Kocjan
Date: Wed, 13 Jul 2005 06:11
73 lines
3237 bytes
kokoryn napisał(a):
> witam
> 
> Piszę skrypt, w którym tworzę dynamicznie kilka procedur wg pewnego
> schematu. Każda taka procedura ma oczywiście inną nazwę i chciałbym
> żeby ta nazwa mogła posłużyć jako indeks w globalnej tablicy, gdzie
> każda procedura będzie mogła przechowywać jakieś swoje dane. Z grubsza
> wygląda to tak:
> 
> array set tab {}
> 
> proc create_proc {name}\
> {
>   proc $name {}\
>   {
>     global tab
>     set tab(???) costam
>   }
> }

Prościej byłoby to zrobić w ten sposób:

proc create_proc {name params body} {
     # mybody wstawione bedzie na poczatku procedury
     set mybody ""

     # sprawia, ze zmienna np ::tab(jakasfunkcja) bedzie w tej
     # procedurze widoczna jakos zmienna lokalna mytab
     append mybody "upvar #0 ::tab($name) mytab" \n

     # stworzenie procedury - mozna nawet skorzystac z [uplevel]
     proc $name $params "$mybody\n$body"
}

Wtedy robisz sobie:

create_proc jakasfunkcja {} {
     set mytab 10
}

Bardzo czesto prosciej jest robic to inaczej:

namespace eval dane {}

proc jakasfunkcja {} {
     upvar #0 ::dane::jakasfunkcja mojedane
     return "Moje dane to $mojedane"
}

Nie ma sensu dla jednej linijki tworzyc automatu.

> W jaki sposób powinienem odwołać się do nazwy procedury w miejscu
> oznaczonym "???" tak, aby móc zapisać coś do tablicy pod odpowiednim
> indeksem? Wydawało mi się, że polecenie info powinno dawać taką
> możliwość, ale z dokumentacji wynika, że nie daje.

set nazwamojejprocedury [lindex [info level [info level]] 0]

Nie jest to najprostsze, ale bardzo logiczne, wystarczy o [info level] 
poczytac :-)

> Przy okazji chciałem powiedzieć, że jestem trochę zawiedziony tak małą
> aktywnością na pl.comp.lang.tcl. Nie spodziewałem się wprawdzie
> jakiegoś wielkiego ruchu, ale na pl.comp.lang.c i pl.comp.programming
> cały czas przewijają się jakieś dygresje (czasem nawet całe dyskusje)
> o Tcl (stąd zresztą dowiedziałem się o tym języku), więc sądziłem, że
> ludzie biorący w nich udział będą pisać tutaj, gdy grupa ruszy. Cóż,
> mam nadzieję, że z czasem grupa się rozkręci.

No ale trochę to rozkręcanie grupy potrwa...

-- 
WK
Re: Jak odwołać się do nazwy procedury?
#121
Author: Wojciech Kocjan
Date: Wed, 13 Jul 2005 06:18
34 lines
2497 bytes
Derek Kuliński / takeda napisał(a):
> On Tue, 12 Jul 2005 23:21:12 +0200, kokoryn wrote:
> 
> 
>>Jest to jakiś pomysł (przy okazji - znaki "\" nie są tu niezbędne).
>>Jednak wydaje mi się, że to rozwiązanie byłoby dobre tylko dla tak
>>trywialnej procedury. Każde odwołanie się do jakiejś zmiennej w ciele
>>procedury zostałoby rozwinięte w momencie stworzenia procedury i
>>trzeba byłoby sporo się namęczyć, żeby to obejść, a efekt byłby bardzo
>>nieelegancki. Jestem przekonany, że istnieje jakiś ładny sposób.
> Wątpię, co Ty chcesz robić to coś co samo modyfikujący się kod, a to raczej
> rzadko było eleganckie.

Aaaa, opowiadasz.

http://cvs.sourceforge.net/viewcvs.py/dqsoftware/tcldb/lib/tcldb/gui/qwidget.tcl?rev=1.6&view=markup

On kreuje kod w całości dynamicznie - opisujesz w miarę szybko jakieś 
większe formatki, a on to przerabia sam do kodu.

Kwestia tylko taka, żeby nie robić metaprogramowania dla sztuki, ale gdy 
jest to potrzebne. Tutaj IMHO nie jest.

>>Cóż, ja sam byłem dotąd tylko i wyłącznie biernym użytkownikiem
>>usenetu, ale jak powstała grupa o Tcl, to zdecydowałem się tutaj
>>pisać, więc chciałbym, żeby coś się tu działo ;).
> No nie będzie się nic działo jak nikt nie będzie zadawał pytań czy udzielał
> odpowiedzi =)

To ja Wam dam takie pytanie, że nikt nie odpowie. Coś jak Lepper i jego 
egzaminy ;-)

-- 
WK
Re: Jak odwołać się do nazwy procedury?
#126
Author: Wojciech Kocjan
Date: Wed, 13 Jul 2005 06:25
64 lines
3137 bytes
kokoryn napisał(a):
> Jest mi to potrzebne do uzyskania modelu podobnego do tego, jaki jest
> stosowany przy tworzeniu widgetów w Tk. Tam każdy widget ma swoją
> procedurę - u mnie analogicznie każda procedura obsługuje pewien
> "obiekt", którego stan muszę przechowywać pomiędzy kolejnymi
> wywołaniami procedury. Mógłbym to zrobić za pomocą zmiennych
> globalnych, ale nie chcę zaśmiecać globalnej przestrzeni nazw, więc
> pomyślałem, że będę trzymał te dane w jednej globalnej tablicy. Może
> to jest wyważanie otwartych drzwi, ale chyba nie - nic mi nie wiadomo
> o jakimś odpowiedniku słowa kluczowego static z C++ w Tcl.

Jest wiele przykładów na Wiki. Na początek błagam pomyśl o IncrTcl - 
robienie mini OO jako "sztuka dla sztuki" nie jest dobre. Jeśli 
koniecznie nie chcesz to napisz chociaż dlaczego.

Jeśli już nie może być Itcl, to jest taki bardzo fajny trik:

# obsluguje obiekt
proc obsluga_obiektu {id cmd args} {
     upvar ::daneobiektu($id) dane
     switch -- $cmd {
         inicjalizuj {
             set dane 0
         }
         pobierz {
             return $dane
         }
         ustaw {
             set dane [lindex $args 0]
         }
         dodaj {
             incr dane
         }
         skasuj {
             unset dane
             rename $id {}
         }
     }
}

# tworzy obiekt
proc obiekt {nazwa} {
     set body ""
     append body "return \[eval \[concat"
     append body " \[list obsluga_obiektu $nazwa\]"
     append body " \$cmd \$args\]\]"
     proc $nazwa {cmd args} $body

     # zainicjalizuj wartosc - niekoniecznie, ale jest ladniej
     $nazwa inicjalizuj
}

Przy okazji zmiana obsługi jak dany "obiekt" działa moze po prostu być 
zrobiona poprzez source pliku z procedurą obsluga_obiektu.

>>Wiesz grupa jest nowa, i raczej dużo osób nie wie. Jeżeli na innej grupie
>>widzisz, że ktoś dyskutuje o tcl, możesz poinformować że taka grupa
>>niedawno zostałą stworzona.
> Chyba jest to rozsądne rozwiązanie.

Może follow up :-)

-- 
WK
Re: Jak odwołać się do nazwy procedury?
#122
Author: kokoryn
Date: Sun, 17 Jul 2005 14:20
25 lines
2008 bytes
On Tue, 12 Jul 2005 18:06:21 -0700, Derek Kuliński / takeda
<d.kulinski@gmail.com> wrote:

>> [...] Jestem przekonany, że istnieje jakiś ładny sposób.
>
>Wątpię, co Ty chcesz robić to coś co samo modyfikujący się kod, a to raczej
>rzadko było eleganckie.

Tworzenie funkcji w locie to chyba dosyć powszechna praktyka w
językach interpretowanych, prawda? Poza tym przecież Tk działa na tej
zasadzie i jest eleganckie i proste w użyciu. Incr Tcl z tego co wiem
też działa jakoś podobnie.

>Ale nie możesz np używać namespaces, albo incr tcl (to bodajże obiektowy
>tcl, więc powinien mieć coś takiego wbudowane).

Myślałem o użyciu namespaces, a Incr Tcl jeszcze nie próbowałem
używać. Tak naprawdę to nie jest to jakiś realny problem wymagający
konkretnego rozwiązania. Chciałem się dowiedzieć jak osiągnąć coś
takiego w celach edukacyjnych.

>No nie będzie się nic działo jak nikt nie będzie zadawał pytań czy udzielał
>odpowiedzi =)

Zgadza się. Właśnie dlatego zacząłem pisać ;).
Re: Jak odwołać się do nazwy procedury?
#128
Author: kokoryn
Date: Sun, 17 Jul 2005 14:37
31 lines
2380 bytes
On Wed, 13 Jul 2005 08:11:02 +0200, Wojciech Kocjan
<mojeimie@kocjan.org> wrote:

>Prościej byłoby to zrobić w ten sposób:
>[ciach]
>Nie ma sensu dla jednej linijki tworzyc automatu.

Dziękuję za propozycje rozwiązań (te i w poście obok). Jak napisałem
przed chwilą w innym poście, nie próbuję robić niczego na siłę.
Chciałem po prostu wiedzieć, czy da się odwołać do nazwy procedury z
jej wnętrza. Incr Tcl nie próbowałem jeszcze używać, bo dopiero uczę
się Tcl-a i chciałbym poznać najpierw możliwie dobrze podstawowe
mechanizmy języka. Zresztą Tcl/Tk nauczył mnie, że nowoczesny
dynamiczny język może się doskonale obejść bez modelu obiektowego,
więc nie palę się do Incr Tcl. Przy tym muszę przyznać, że nie do
końca rozumiem stwierdzenie z Twojej poprzedniej wiadomości o robieniu
"mini OO". Przecież ja tak naprawdę nie wprowadzam żadnych obiektów, w
końcu wszystkie procedury tworzone przez create_proc to w istocie ta
sama procedura tyle, że z dodatkowym "argumentem" przekazanym jakby
przez jej nazwę, która ma operować na jakiejś tam strukturze danych.
Po prostu taki cukier składniowy, ale całkiem ładnie wygląda moim
zdaniem.

>set nazwamojejprocedury [lindex [info level [info level]] 0]
>
>Nie jest to najprostsze, ale bardzo logiczne, wystarczy o [info level] 
>poczytac :-)

Właśnie o coś takiego chodziło! Przeoczyłem to, bo przeleciałem
wzrokiem po dokumentacji i przeczytałem tylko co info level zwraca bez
argumentu, mój błąd.
Re: Jak odwołać się do nazwy procedury?
#123
Author: Wojciech Kocjan
Date: Sun, 17 Jul 2005 14:44
58 lines
3819 bytes
kokoryn napisał(a):
> On Tue, 12 Jul 2005 18:06:21 -0700, Derek Kuliński / takeda
> <d.kulinski@gmail.com> wrote:
> 
> 
>>>[...] Jestem przekonany, że istnieje jakiś ładny sposób.
>>
>>Wątpię, co Ty chcesz robić to coś co samo modyfikujący się kod, a to raczej
>>rzadko było eleganckie.
> 
> 
> Tworzenie funkcji w locie to chyba dosyć powszechna praktyka w
> językach interpretowanych, prawda? Poza tym przecież Tk działa na tej
> zasadzie i jest eleganckie i proste w użyciu. Incr Tcl z tego co wiem
> też działa jakoś podobnie.

Mniejwięcej tak. Nie wiem tylko dlaczego nie skorzystałbyś z Incr Tcl 
lub innego systemu obiektowego? Ja korzystam z Incr Tcl, podobno XOTcl 
jest bardziej Tcl-owy, ale mniej przypomina model z C++/Javy, a więc 
ciężej go załapać. Ja póki co się nie skusiłem na sprawdzenie co to 
oznacza :-)

>>Ale nie możesz np używać namespaces, albo incr tcl (to bodajże obiektowy
>>tcl, więc powinien mieć coś takiego wbudowane).
> Myślałem o użyciu namespaces, a Incr Tcl jeszcze nie próbowałem
> używać. Tak naprawdę to nie jest to jakiś realny problem wymagający
> konkretnego rozwiązania. Chciałem się dowiedzieć jak osiągnąć coś
> takiego w celach edukacyjnych.

Rozwiązań jest tyle ilu ludzi, którzy rozumieją dynamiczność Tcl - Tcl 
to jedyny chyba język dynamiczny (skryptowy już nie jest trendy podobno 
bo się kojarzy z kodem do 200 linii), gdzie całą obiektowość zrobić nim 
samym. Popatrz sobie np na ilość rozwiązań lambdy. Jeśli możesz, 
korzystaj z Incr Tcl.

Incr Tcl wiąże się z tym, że na docelowych maszynach musi być Incr Tcl 
albo dajesz wersję binarną - z czym jest problem pod Linuxem z kolei :(, 
więc jeśli natomiast nie możesz lub nie chcesz go używać, to jest 
conajmniej 5 możliwości, nie ma "The Right Way(TM)", bo Tcl jest na tyle 
dynamiczny, że nie musi być.

Namespace sam w sobie nie służy do tworzenia obiektów, natomiast pomaga 
w zarządzaniu modułami - każdy moduł może mieć zmienne globalne w danym 
namespace, dzięki czemu trudniej o kolizje (chociaż daleko tu do 
Sunowskiego pomysłu z domenami).

Namespace jest na pewno pomocny, chociażby do trzymania danych 
kontekstowych, jeśli już robisz OO samemu.

>>No nie będzie się nic działo jak nikt nie będzie zadawał pytań czy udzielał
>>odpowiedzi =)
> Zgadza się. Właśnie dlatego zacząłem pisać ;).

To może niech każdy się przedstawi w osobnym wątku - w kontekście Tcl 
oczywiście, zrobimy ruch a i na temat będzie :-)

-- 
WK
Re: Jak odwołać się do nazwy procedury?
#129
Author: Wojciech Kocjan
Date: Sun, 17 Jul 2005 14:49
66 lines
3919 bytes
kokoryn napisał(a):
> On Wed, 13 Jul 2005 08:11:02 +0200, Wojciech Kocjan
> <mojeimie@kocjan.org> wrote:
> 
> 
>>Prościej byłoby to zrobić w ten sposób:
>>[ciach]
>>Nie ma sensu dla jednej linijki tworzyc automatu.
> 
> 
> Dziękuję za propozycje rozwiązań (te i w poście obok). Jak napisałem
> przed chwilą w innym poście, nie próbuję robić niczego na siłę.

Ok. To już wiesz, że jak będziesz coś chciał zrobić to wtedy zależy od 
rozwiązania. korzystanie z OO dla 100 linijek kodu, w aplikacji o 50k 
kodu nie ma sensu - natomiast robienie całej aplikacji albo jej 
większości w OO ma sens. Ja robię kontrolki i mechanizmy w OO, a obsługę 
bez OO - wtedy można przeładować kilka procedur bez restartu.

> Chciałem po prostu wiedzieć, czy da się odwołać do nazwy procedury z
> jej wnętrza. Incr Tcl nie próbowałem jeszcze używać, bo dopiero uczę
> się Tcl-a i chciałbym poznać najpierw możliwie dobrze podstawowe
> mechanizmy języka. Zresztą Tcl/Tk nauczył mnie, że nowoczesny
> dynamiczny język może się doskonale obejść bez modelu obiektowego,
> więc nie palę się do Incr Tcl.

Aha. Co do obywania się bez, to ja bardzo chwalę sobie [Incr Tk], bo nie 
czuje się różnicy między Tk a megawidgetami (poza bindowaniem, to jest 
koszmar Incr Tk niestety.

> Przy tym muszę przyznać, że nie do
> końca rozumiem stwierdzenie z Twojej poprzedniej wiadomości o robieniu
> "mini OO". Przecież ja tak naprawdę nie wprowadzam żadnych obiektów, w
> końcu wszystkie procedury tworzone przez create_proc to w istocie ta
> sama procedura tyle, że z dodatkowym "argumentem" przekazanym jakby
> przez jej nazwę, która ma operować na jakiejś tam strukturze danych.
> Po prostu taki cukier składniowy, ale całkiem ładnie wygląda moim
> zdaniem.

No ale właśnie to co Ty robisz działa dokładnie tak samo jak OO w Tcl. 
Dlatego każdemu się skojarzyło :-)

>>set nazwamojejprocedury [lindex [info level [info level]] 0]
>>Nie jest to najprostsze, ale bardzo logiczne, wystarczy o [info level] 
>>poczytac :-)
> Właśnie o coś takiego chodziło! Przeoczyłem to, bo przeleciałem
> wzrokiem po dokumentacji i przeczytałem tylko co info level zwraca bez
> argumentu, mój błąd.

Aha, kolejne rozwiązanie to [interp alias].

% proc dumpargs {args} {puts $args}
% interp alias {} dumpx {} dumpargs x
% dumpargs a b c
a b c
% dumpx a
x a

To pozwala, żeby 1szy parametr prawdziwej procedury to była nazwa 
danych, a create_proc wtedy tworzy zmienną (lub tablicę) z danymi 
lokalnymi + robi alias. Nie podałem całego przykładu, bo mi się po 
prostu nie chce :-). Dopiszesz sobie. To chyba najładniejsze 
rozwiązanie, bez czarowania z introspekcją :-)

-- 
WK
Re: Jak odwołać się do nazwy procedury?
#125
Author: Wojciech Kocjan
Date: Sun, 17 Jul 2005 22:43
30 lines
2280 bytes
Googie napisał(a):
> Wojciech Kocjan wrote:
> 
> 
>>Incr Tcl wiąże się z tym, że na docelowych maszynach musi być Incr
>>Tcl albo dajesz wersję binarną - z czym jest problem pod Linuxem z
>>kolei :(
> 
> 
> No nie do końca...
> 
> IncrTcl jest np w TclKit'cie, co stanowi prosty sposób na jego
> dystrybucję wraz z programem.

Tak, wiem, nie zapominaj, że sam zrobiłem nawet własny fork o nazwie 
dqkit (dqsoftware na sourceforge).

> Osobiście używam SDX'a do zwijania
> aplikacji razem z TclKitem jako 'runtime' i wtedy nie ma problemu z
> ITcl, a często załatwia to też problem ewentualnych innych rozszerzeń.
> Niedawno testowałem działanie aplikacji przygotowanej w ten sposób,
> zawierającej w sobie IncrTcl (z TclKita), Zinc, TclMixer, Tile, oraz
> Img. Ja używam Slackware 10.1, a poszło u znajomego z Mandrake 10.0,
> oraz Debian Sid, czy jakoś tak, więc nie jest źle.

Jak już działa to jest super. Gorzej to skompilować, żeby działało 
wszędzie. Mój na przykład sypie się na RHEL.

-- 
WK
Re: Jak odwołać się do nazwy procedury?
#124
Author: Googie
Date: Sun, 17 Jul 2005 23:51
22 lines
1859 bytes
Wojciech Kocjan wrote:

> Incr Tcl wiąże się z tym, że na docelowych maszynach musi być Incr
> Tcl albo dajesz wersję binarną - z czym jest problem pod Linuxem z
> kolei :(

No nie do końca...

IncrTcl jest np w TclKit'cie, co stanowi prosty sposób na jego
dystrybucję wraz z programem. Osobiście używam SDX'a do zwijania
aplikacji razem z TclKitem jako 'runtime' i wtedy nie ma problemu z
ITcl, a często załatwia to też problem ewentualnych innych rozszerzeń.
Niedawno testowałem działanie aplikacji przygotowanej w ten sposób,
zawierającej w sobie IncrTcl (z TclKita), Zinc, TclMixer, Tile, oraz
Img. Ja używam Slackware 10.1, a poszło u znajomego z Mandrake 10.0,
oraz Debian Sid, czy jakoś tak, więc nie jest źle.

StarKity rządzą :)

-- 
Pozdrawiam (Greetings)!
Googie
Re: Jak odwołać się do nazwy procedury?
#130
Author: Artur
Date: Fri, 29 Jul 2005 07:38
113 lines
4308 bytes
kokoryn schrieb:

> witam
>
> Piszę skrypt, w którym tworzę dynamicznie kilka procedur wg pewnego
> schematu. Każda taka procedura ma oczywiście inną nazwę i chciałbym
> żeby ta nazwa mogła posłużyć jako indeks w globalnej tablicy, gdzie
> każda procedura będzie mogła przechowywać jakieś swoje dane. Z grubsza
> wygląda to tak:
>
> array set tab {}
>
> proc create_proc {name}\
> {
>   proc $name {}\
>   {
>     global tab
>     set tab(???) costam
>   }
> }
>

Kilka komentarzy
1) Nazwe procedury mozna otrzymac przez introspekcje:
   info level 1
2) jesli procedury roznia sie tylko nazwa, ktora jest uzywana dla
   dostepu do jakis globalnych dannych to lepiej posluzyc sie nazwa
jako referencja do danych

    proc universal name {
        set ::tab($name) costam
    }
   Rozwiazanie jest nawet lepsze bo nie definiuje zbyt duzo proc
   co zasmieca pamiec

   uzycie jest prawie te samo zamiast
   $name
   universal $name


  W Tk mozna czesto zauwazyc podobny kod

    proc handler struct_ref {
         upvar #0 $struct_ref mydata
         set mydata 2
    }

  upvar umozliwia uzywanie zmiennej mydata jakby lokalnej (nawet jako
array)

3) Czesto zamiast definiowac procs w locie lepiej poprostu trzymac
skrypty
   i uzywac eval. Tak dziala Tk w opciach -command script

   set script($name) "......"
   eval script($name)

   Tu nie ma tak duzo problemow z kontekstem zmiennych (scoping).
   W Tcl wszystko jest "string" .

4) Uzywanie duzej ilosci globalnych zmiennych nie jest czesto dobrym
pomyslem.
   (bo ponowne uzycie albo przejzystosc programu, side effects).
   Najlepsze procedury to takie ktore wogole nie maja "side effects",
czyli
   sa niezalezne od globalnego kontekstu i nie zmieniaja go.
   To odpowiada matematycznej idei funkcji.

   Mozna co prawda definiowac namespaces co takze robi Tk ale to tak
naprawde
   nie robi wielkiej roznicy.

   namespace eval ::private { variable data costam }
   proc handler struct_ref {
         upvar ::private_namespace::$struct_ref mydata
         puts $mydata
    }
    handler data

   Takie zabawy nie sa ale dla poczatkujacych

5) Reczywiscie wszystkie pure-Tcl OO-frameworks
   (i Tk) uzywaja podobnych schematow.
   Nazwa objektu jest nazwa procedury, ktora obsluguje metody objektu.
   I w tym momecie juz prawie konstrujemy nowy OO-framework dla Tcl.
   Glowna idea OO jest miec dane i funkcje na danych w jednym miejscu
   (objekcie).
   W celach edukacyjnych mozna przez podobne przyklady wytlumacyc
   poco OO istnieje. Chociaz wydaje mi sie, ze objekty sa
   idea bardziej naturalna nie procedury.


   Przyklad w XOTcl

   package requrie XOTcl
   Class Myclass -parameter tab
   Myclass instproc doit {} {
      my instvar tab
      puts $tab
   }
   # uzycie
   Myclass create myInstace -tab costam
   myInstance doit


   Oczywiscie XOTcl jest bardziej dojrzaly i szybszy niz rozwiazania,
   ktore mozna napisac od reki ale dla celow edukacyjnych warto jest
sie
   troche pomeczyc.

(sorry za ogonki, ale nie mam polskiego systemu)

Artur Trzewik
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads