-
11. Data: 2012-06-04 16:14:17
Temat: Re: Try catch, prawidłowy sposób użycia
Od: Maciej Sobczak <s...@g...com>
On 4 Cze, 10:31, zażółcony <r...@c...pl> wrote:
> > Ja najchętniej korzystam z traksakcji z automatycznym rollbackiem,
> > wyzwalanym przez destruktor. Wtedy opcja B jest kompletnie bez sensu
>
> Czyli korzystasz ze wzorca projektowego RAII
Jeśli to tak nazwiesz, to wszyscy wiedzą, o co chodzi, ale specjalnie
tej nazwy nie użyłem, bo w odniesieniu do obsługi transakcji znaczenie
tego skrótu ma się nijak. Ale faktycznie chodzi o to samo.
> (nazwa niezbyt trafna, ale tak już zostało).
> Taką konstrukcję zastosujesz tylko w językach bez asynchronicznie
> działającego garbage collectora, tzn. w takich, w których masz jasno
> zdefiniowany moment odpalania konstruktora.
Destruktora. Nie ma problemu z garbage collectorem, może sobie być i
jedno i drugie. To, że Javie jest tylko jedno to wybór projektantów
języka a nie ograniczenia paradygmatyczne. GC nadaje się do obsługi
pamięci ale nie od obsługi interakcji ze światem zewnętrznym.
> > No właśnie - co to za język programowania?
>
> Jeden z języków, w którym nie masz możliwości zastosowania wzorca RAII.
Fuj. Powinni tego zakazać.
> Wyobraź sobie, że zamiast transakcji masz tam operację otwarcia pliku,
[...]
> Zauważ, że jeśli wrzucisz otwieranie po try, to potem w finally musisz
> się zastanawiać, czy robić close, czy nie (dodatkowy if). A tego właśnie
> chcemy uniknąć.
Ja tego unikam używając języków, gdzie mogę mieć normalne RAII. Bo
zastanawianie się, gdzie postawić begin względem try to odwracanie
uwagi od głównego zagadnienia, typowe dla języków niskiego poziomu.
--
Maciej Sobczak * http://www.msobczak.com * http://www.inspirel.com
-
12. Data: 2012-06-04 16:24:06
Temat: Re: Try catch, prawidłowy sposób użycia
Od: Edek Pienkowski <e...@g...com>
Dnia Mon, 04 Jun 2012 14:52:50 +0200, AK napisal:
> Użytkownik "Maciej Sobczak" <s...@g...com> napisał:
>
>> Ten kod może być zarówno dobry jak i niedobry, zależnie od kontekstu.
>
> Ten kod (A) jest zawsze zly.
Nie jest, to znaczy nie zawsze
> Tak jak zawsze zly jest kod typu:
>
> FILE* f;
>
> try {
> f = fopen(...); ....
> flose(f);
> {
> catch ( ... ):
> {
> ...
> flose(f);
> ...
> }
if (f != null) { fclose(f);};
Bardzo często używa się nulli w ten sposób, lub czego
innego co ma wartość typu "nic". Spróbuj napisać większą
logikę, wymagałoby wielu zagnieżdżonych try/catch,
a można zrobić jedno catch czy finally i sprawdzać,
co już zostało a) zainicjalizowane b) jest jeszcze nie
zamknięte, bo to też trzeba uwzględnić jak się zamyka
kilka rzeczy po kolei.
>
> czy typu:
>
> Object* obj;
>
> try {
> obj = new Object();
> ....
> delete obj;
> }
> catch ( ... ):
> {
> ...
> delete obj;
> ...
> }
ditto. Tu nawet w c++ jak się zainicjalizuje
obj = null na początku to delete nic nie zrobi.
Edek
-
13. Data: 2012-06-04 18:04:43
Temat: Re: Try catch, prawidłowy sposób użycia
Od: zażółcony <r...@c...pl>
W dniu 2012-06-04 16:14, Maciej Sobczak pisze:
> On 4 Cze, 10:31, zażółcony<r...@c...pl> wrote:
>
>>> Ja najchętniej korzystam z traksakcji z automatycznym rollbackiem,
>>> wyzwalanym przez destruktor. Wtedy opcja B jest kompletnie bez sensu
>>
>> Czyli korzystasz ze wzorca projektowego RAII
>
> Jeśli to tak nazwiesz, to wszyscy wiedzą, o co chodzi, ale specjalnie
> tej nazwy nie użyłem, bo w odniesieniu do obsługi transakcji znaczenie
> tego skrótu ma się nijak. Ale faktycznie chodzi o to samo.
Skrót jest kiepski, ale pojęcie transakcji i pojęcie zasobu
już nie są tak odległe. Do transakcji i pliku jako 'bazę przykładów'
dałbym jeszcze 'mutex', lub inaczej semafor binarny.
W przypadku tego ostatniego sytuacja wydaje mi się najbardziej
jaskrawa: semafor opuszczasz PRZED try, a podnosisz w finally.
Każda inna konstrukcja to prośba o brak parzystości operacji na semaforze.
W przypadku transakcji bd masz:
begin = alokacja zasobu (abstrakcyjna rezerwacja zasobów bazy danych),
commmit = zapis zasobu + jego zwolnienie,
rollback = obsługa błędu + jego awaryjne zwolnienie.
Z powyższego masz wprost widoczne, dlaczego begin jest przed try
a commit i rollback 'w środku'.
>> (nazwa niezbyt trafna, ale tak już zostało).
>> Taką konstrukcję zastosujesz tylko w językach bez asynchronicznie
>> działającego garbage collectora, tzn. w takich, w których masz jasno
>> zdefiniowany moment odpalania konstruktora.
>
> Destruktora. Nie ma problemu z garbage collectorem, może sobie być i
> jedno i drugie. To, że Javie jest tylko jedno to wybór projektantów
> języka a nie ograniczenia paradygmatyczne. GC nadaje się do obsługi
> pamięci ale nie od obsługi interakcji ze światem zewnętrznym.
Myśląnad tym - patrz 'closures'. Ale jest to problem w Javie
dobrze rozpracowany za pomocą innych wzorców, jeden właśnie taki,
o jakim mowa - try-catch-finally. Problem jest trochę, jak
obiekt wyskakuje 'na zewnątrz', kiedy pełny cykl jego życia
trudno objąć jedną funkcją. Wtedy jest trochę zabawy, ale generalnie
da się z tym całkiem dobrze żyć.
>
>>> No właśnie - co to za język programowania?
>>
>> Jeden z języków, w którym nie masz możliwości zastosowania wzorca RAII.
>
> Fuj. Powinni tego zakazać.
Po przesiadce z c++ na Javę też nie mogłem się początkowo
w tym odnaleźć, ale po kilku latach kompletnie mi nie żal :)
Do destruktorów absolutnie nie tęsknię :)
>> Wyobraź sobie, że zamiast transakcji masz tam operację otwarcia pliku,
> [...]
>> Zauważ, że jeśli wrzucisz otwieranie po try, to potem w finally musisz
>> się zastanawiać, czy robić close, czy nie (dodatkowy if). A tego właśnie
>> chcemy uniknąć.
>
> Ja tego unikam używając języków, gdzie mogę mieć normalne RAII. Bo
> zastanawianie się, gdzie postawić begin względem try to odwracanie
> uwagi od głównego zagadnienia, typowe dla języków niskiego poziomu.
Imo nie jest to większe odwracanie uwagi, niż wtedy, gdy
np. z założenia pchasz wrażliwe operacje w konstruktory obiektów
i potem musisz się zastanawiać, czy obiekt, który utworzyłeś
na pewno się w pełni zainicjalizował, czy mu czegoś brakuje
i czy przypadkiem destruktor się nie wypierniczy. A wywaka w
konstruktorze to w przypadku niektórych języków jest sprawa
bardzo brzydka. Akurat walczę z tematem przy okazji konstruowania
obiektów OLE z poziomu języka FoxPro.
BTW. Automatyczny 'rollback' w destruktorze obiektu transakcji też
ćwiczyłem. Dopóki ktoś nie zapomni o commicie brzmi cukierkowo :)
Imo w tym wypadku zamiast konstrukcji typu TransactionScope
czy RAII podobnych lepiej korzystać z abstrakcji
oddzielających kwestie bazy danych od logiki biznesowej
(transakcyjność jako aspekt, zewnętrzny manager transakcji
automagicznie otaczający dostarczoną funkcję biznesową
transakcją - tak, jak to się robi obecnie w Javie i w C#
zdaje się również).
-
14. Data: 2012-06-04 19:21:50
Temat: Re: Try catch, prawidłowy sposób użycia
Od: Edek Pienkowski <e...@g...com>
Dnia Mon, 04 Jun 2012 18:04:43 +0200, zażółcony napisal:
> W dniu 2012-06-04 16:14, Maciej Sobczak pisze:
>> On 4 Cze, 10:31, zażółcony<r...@c...pl> wrote:
>>
>>>> Ja najchętniej korzystam z traksakcji z automatycznym rollbackiem,
>>>> wyzwalanym przez destruktor. Wtedy opcja B jest kompletnie bez sensu
>>>
>>> Czyli korzystasz ze wzorca projektowego RAII
>>
>> Jeśli to tak nazwiesz, to wszyscy wiedzą, o co chodzi, ale specjalnie
>> tej nazwy nie użyłem, bo w odniesieniu do obsługi transakcji znaczenie
>> tego skrótu ma się nijak. Ale faktycznie chodzi o to samo.
>
> Skrót jest kiepski, ale pojęcie transakcji i pojęcie zasobu już nie są
> tak odległe. Do transakcji i pliku jako 'bazę przykładów' dałbym jeszcze
> 'mutex', lub inaczej semafor binarny.
> W przypadku tego ostatniego sytuacja wydaje mi się najbardziej jaskrawa:
> semafor opuszczasz PRZED try, a podnosisz w finally.
> Każda inna konstrukcja to prośba o brak parzystości operacji na
> semaforze.
Mutex to nie jest semafor. Nie ma problemu z zamykaniem go w try. To
znaczy tak samo nie ma problemu jak i poza try, ogólnie musi być
otwarty jeżeli został zamknięty, ale w try/catch można to zamknąć
bardzo różnie, zazwyczaj przez obiekt guarda lokalny dla wątku,
który tylko po to istnieje żeby to obsłużyć.
Edek
-
15. Data: 2012-06-04 23:13:15
Temat: Re: Try catch, prawidłowy sposób użycia
Od: " M.M." <m...@N...gazeta.pl>
Stachu 'Dozzie' K. <d...@g...eat.some.screws.spammer.invalid> napisał(a):
> On 2012-06-04, AK <n...@n...com> wrote:
> > Użytkownik "Maciej Sobczak" <s...@g...com> napisał:
> >
> >> Ten kod może być zarówno dobry jak i niedobry, zależnie od kontekstu.
> >
> > Ten kod (A) jest zawsze zly.
> > Tak jak zawsze zly jest kod typu:
> [...]
> > flose(f);
> [...]
> > delete obj;
>
> Zakładasz niesłusznie, że bezwzględnie wywołane fclose() i bezwzględnie
> wywołane delete są równoważne operacji rollback.
Może być poprawny. Wystarczy że w danym języku new zwróci null gdy
się nie uda allokacja i delete jest odporne na null (odporne czyli
nie wykrzacza się na null).
Pozdrawiam
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
16. Data: 2012-06-04 23:19:23
Temat: Re: Try catch, prawidłowy sposób użycia
Od: " M.M." <m...@N...gazeta.pl>
Edek Pienkowski <e...@g...com> napisał(a):
> Tu nawet w c++ jak siÄ zainicjalizuje
> obj = null na poczÄ tku to delete nic nie zrobi.
Faktycznie delete nie wywala się gdy otrzyma null.
Trochę się zdziwiłem, pamiętam że się wywalało.
To kwestia opcji/kompilatora ?
Pozdrawiam
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
17. Data: 2012-06-05 00:47:26
Temat: Re: Try catch, prawidłowy sposób użycia
Od: n...@m...invalid
W dniu 4.06.2012 r. 23:19, M.M. pisze:
> Edek Pienkowski <e...@g...com> napisał(a):
>
>> Tu nawet w c++ jak siÄ zainicjalizuje
>> obj = null na poczÄ tku to delete nic nie zrobi.
> Faktycznie delete nie wywala się gdy otrzyma null.
> Trochę się zdziwiłem, pamiętam że się wywalało.
> To kwestia opcji/kompilatora ?
Tak. Ściśle rzecz biorąc, w C++ to UB. RT może to milcząco zignorować,
wykonać nieoczekiwane zatrzymanie, lub cokolwiek.
-
18. Data: 2012-06-05 07:25:26
Temat: Re: Try catch, prawidłowy sposób użycia
Od: "Waldek M." <w...@l...localdomain>
Dnia Tue, 05 Jun 2012 00:47:26 +0200, n...@m...invalid napisał(a):
>> Faktycznie delete nie wywala się gdy otrzyma null.
>> Trochę się zdziwiłem, pamiętam że się wywalało.
>> To kwestia opcji/kompilatora ?
> Tak. Ściśle rzecz biorąc, w C++ to UB. RT może to milcząco zignorować,
> wykonać nieoczekiwane zatrzymanie, lub cokolwiek.
Obawiam się, że nie masz racji.
Standard 5.3.5, par. 1,2 (expr. delete):
The first alternative is for non-array objects, and the second is for
arrays.[...] In the first alternative (delete object), the value of the
operand of delete may be a null pointer
value, a pointer to a non-array object created by a previous
new-expression, or a pointer to a subobject (1.8)
representing a base class of such an object (Clause 10). If not, the
behavior is undefined.
Delete na NULL jest jak najbardziej dopuszczalny i nie jest to UB.
Pozdrawiam,
Waldek
-
19. Data: 2012-06-05 08:43:17
Temat: Re: Try catch, prawidłowy sposób użycia
Od: zażółcony <r...@c...pl>
W dniu 2012-06-04 19:21, Edek Pienkowski pisze:
> Mutex to nie jest semafor. Nie ma problemu z zamykaniem go w try. To
Trochę odbiegamy od tematu, ale ...
Wrzuciłem w google 'mutex', kliknąłem w pierwszy lepszy link:
http://koti.mbnet.fi/niclasw/MutexSemaphore.html
i masz:
"A mutex is really a semaphore with value 1."
:)
I właśnie to dokładnie miałem na myśli.
-
20. Data: 2012-06-05 09:01:25
Temat: Re: Try catch, prawidłowy sposób użycia
Od: Edek Pienkowski <e...@g...com>
Dnia Tue, 05 Jun 2012 08:43:17 +0200, zażółcony napisal:
> W dniu 2012-06-04 19:21, Edek Pienkowski pisze:
>
>> Mutex to nie jest semafor. Nie ma problemu z zamykaniem go w try. To
>
> Trochę odbiegamy od tematu, ale ...
> Wrzuciłem w google 'mutex', kliknąłem w pierwszy lepszy link:
> http://koti.mbnet.fi/niclasw/MutexSemaphore.html
>
> i masz:
> "A mutex is really a semaphore with value 1."
> :)
> I właśnie to dokładnie miałem na myśli.
Jak znajdę link w sieci do psoszczura, to uwierzysz że psoszczur
istnieje?
:) W ramach dalszego odbiegania od tematu....
Edek