Форум: "Прочее";
Текущий архив: 2011.10.30;
Скачать: [xml.tar.bz2];
Внизоператор with Найти похожие ветки
← →
cross (2011-07-01 16:27) [0]как вы относитесь к оператору with? стоит ли его использовать? прочитал много критики, хотелось бы услышать ваше мнение.
← →
stas © (2011-07-01 16:30) [1]я не использую, но не вижу в его использовании ничего плохого.
← →
Dennis I. Komarov © (2011-07-01 16:31) [2]вполне нормально, а что не так?
← →
Kerk © (2011-07-01 16:38) [3]В ситуациях типа:
with TForm.Create do
try
...
finally
Free;
end;
отношусь хорошо.
В остальных - плохо. Читаемость убивает нахрен.
← →
asail © (2011-07-01 16:44) [4]
> Kerk © (01.07.11 16:38) [3]
+1
← →
antonn © (2011-07-01 16:45) [5]
> В ситуациях типа:
а я наоборот не люблю когда Create в блоке :)
← →
alexdn © (2011-07-01 16:56) [6]> antonn © (01.07.11 16:45) [5]
>
> > В ситуациях типа:
>
> а я наоборот не люблю когда Create в блоке :)
а что ж тогда остается..? show, visible..?
← →
Anatoly Podgoretsky © (2011-07-01 16:56) [7]> cross (01.07.2011 16:27:00) [0]
И что, прочитаного не хватает.
← →
antonn © (2011-07-01 17:07) [8]
> а что ж тогда остается..?
я переменную завожу
← →
clickmaker © (2011-07-01 17:08) [9]> как вы относитесь к оператору with?
к любому оператору можно относиться, как к молотку, например. Кто-то забьет аккуратно гвоздь и повесит картину. А кто-то палец себе отобъет.
← →
SQLEXPRESS (2011-07-01 17:09) [10]вот, например, кто на вскидку угадает?
TA = class
public
AVal : Integer;
BVal : Integer;
end;
TB = class
public
AVal : Integer;
BVal : Integer;
end;
procedure TForm1.btn1Click(Sender: TObject);
var
A:TA;
B:TB;
begin
A := TA.Create;
B := TB.Create;
A.AVal := 11;
A.BVal := 22;
B.AVal := 111;
B.BVal := 222;
with A do
with B do
AVal := BVal;
end;
← →
Dennis I. Komarov © (2011-07-01 17:10) [11]Если дальше ссылаться не надо, то нафига переменныя?
напримет:with TRegistry.Create do try
//читаем/пишем
finally
Free;
end;
← →
Dennis I. Komarov © (2011-07-01 17:12) [12]
> with A do
> with B do
with A, B do...
а чего тут угадывать?
← →
SQLEXPRESS (2011-07-01 17:20) [13]
> а чего тут угадывать?
ну.. какие значения будут у всех 4х полей?
← →
Игорь Шевченко © (2011-07-01 17:59) [14]
> как вы относитесь к оператору with? стоит ли его использовать?
>
Как вы относитесь к оператору for ? Стоит ли его использовать ? Не лучше ли использовать while ?
Как вы относитесь к оператору case ? Стоит ли его использовать ? Не лучше ли использовать if ?
← →
TUser © (2011-07-01 20:08) [15]Я использую, и часто, потому что это сокращает код, следовательно делает его читабельнее.
> прочитал много критики
Критика обычно основана на том, что из кода не понятно, свойство или метод чего имеются ввиду. Это затрудняет отладку. У меня такая путаница бывает очень редко, это одна из экзотических ошибок.
← →
TUser © (2011-07-01 20:14) [16]
> Читаемость убивает нахрен.procedure AllAtoms (Protein: TProtein; Func: TAllAtomsFunc);
var m, c, r, a: integer;
begin
with Protein do
for m:=0 to ModCount-1 do
with Models[m] do begin
for c:=0 to ChCount-1 do
with Chains[c] do
for r:=0 to ResCount-1 do
with Residues[r] do
for a:=0 to AtCount-1 do begin
if not Func(Atoms[a]) then
exit;
{$ifdef SHOWPDBPROGRESS}
waAddProgress;
{$endif}
end;
with HeteroAtoms do
for a:=0 to AtCount-1 do begin
if not Func(Atoms[a]) then
exit;
{$ifdef SHOWPDBPROGRESS}
waAddProgress;
{$endif}
end;
end;
end;
А теперь, тоже самое без with
if not Func(Protein.Models[m].Chains[c].Residues[r].Atoms[a]) then
exit;
либо
базовый класс, от которого наследники - все классы в иерархии (Protein, Model, etc), имеет метод типа
function TAAA.Enum (Func: ...): boolean;
begin
result := false;
if i am TAtom then
if not Func (Self) then exit;
for i := 0 to ChildCount - 1 do
if not Children[i].Enum (func) then
exit;
end;
Что быстрее? Что читабельнее?
← →
TUser © (2011-07-01 20:16) [17]Разве что последнее оопэшнее, но не стоит использовать ооп вместо мозгов, имхо.
← →
DiamondShark © (2011-07-01 20:17) [18]Когда я писал на дельфи, считал этот оператор условно полезным.
Когда стал писать на C#, забыл, что такой оператор зачем-то нужен.
Формально, это избыточный оператор. Возможностей для написания хорошего и уродского кода он предоставляет примерно поровну.
← →
_Юрий (2011-07-01 20:29) [19]Отладчик отказывается показывать значения свойств и полей этой неявной переменной.
Поэтому использую только в простейших случаях, когда отладка заведомо не требуется, типа [3].
В одном проекте видел with с семью членами - за такое надо уже отрывать руки и вставлять в задницу.
← →
Kerk © (2011-07-01 20:31) [20]
> А теперь, тоже самое без with
>
> if not Func(Protein.Models[m].Chains[c].Residues[r].Atoms[a])
> then
> exit;
Ну и нормально. Намного лучше читается, чем вариант с with.
← →
TUser © (2011-07-01 20:32) [21]
> Отладчик отказывается показывать значения свойств и полей
> этой неявной переменной.
Это глюк отладчика, который есть далеко не всегда.
← →
TUser © (2011-07-01 20:34) [22]
> Ну и нормально. Намного лучше читается, чем вариант с with.
Особенно хорошо читается, когда весь код состоит из такого художества. Ну и исполняется быстро.
← →
Kerk © (2011-07-01 20:35) [23]
> TUser © (01.07.11 20:08) [15]
>
> > прочитал много критики
>
> Критика обычно основана на том, что из кода не понятно,
> свойство или метод чего имеются ввиду. Это затрудняет отладку.
> У меня такая путаница бывает очень редко, это одна из экзотических
> ошибок.
Так это у тебя, потому ты сам написал. Мне же, как человеку постороннему (я же понятия не имею чего там у тебя за структуры и классы), для понимания твоего примера с with требуются мозговые усилия, чего не скажешь о варианте без него.
← →
картман © (2011-07-01 20:35) [24]
> Это глюк отладчика, который есть далеко не всегда.
угу, не всегда, только когда ну очень нада!
← →
TUser © (2011-07-01 20:41) [25]
> я же понятия не имею чего там у тебя за структуры и классы
Возможно ты прав. В данном случае структура дерева точно отражает содержание предметной области. А если ты вознамерился там что-то понять или поправить под себя, то предметную область все равно придется постигать.
Я как будет время проведу такой эксперимент. Покажу этот код людям, которые в паскале не знают ничего, а в программировании и в предметной области разбираются вполне. Замерю время, за которое они сообразят, что тут делается.
← →
DiamondShark © (2011-07-01 20:46) [26]
> А теперь, тоже самое без with
А теперь то же самое без Паскаля:
void AllAtoms(Protein protein, AllAtomFunc func)
{
foreach (var model in protein.Models)
{
foreach (var chain in model.Chains)
foreach (var residue in chain.Residues)
foreach (var atom in residue.Atoms)
{
if (!func(atom)) return;
#if SHOWPDBPROGRESS
waAddProgress();
#enfif
}
foreach (var atom in model.HeteroAtoms)
{
if (!func(atom)) return;
#if SHOWPDBPROGRESS
waAddProgress();
#enfif
}
}
}
Не в with дело, ой, не в with.
← →
* © (2011-07-02 07:12) [27]анохронизм, который должен помереть в страшных муках
бо попробуйте разобраться в чужом коде с width
> TUser © (01.07.11 20:14) [16]
застрелить писателя, если сам не осознал и не застрелился
← →
_Юрий (2011-07-02 11:54) [28]
> Это глюк отладчика, который есть далеко не всегда.
У меня - всегда.
Глюк отладчика - это точно такая же данность, как и синтаксические правила языка, и эта данность должна быть учтена при выборе решения.
Точно также, как и глюки компилятора - если какая то новая фича теоретически должна сделать нам "удобно и быстро", а на практике приходится тратить больше времени на борьбу с internal error, то фича идет лесом.
В теории теория не отделима от практики, но на практике это не так.
По поводу [16] - вариант с with - ужасен.
← →
_Юрий (2011-07-02 12:18) [29]
> DiamondShark © (01.07.11 20:46) [26]
А теперь тоже самое с паскалем:
procedure AllAtoms (Protein: TProtein; Func: TAllAtomsFunc);
var
model: TModel;
chain: TChain;
residue: TResidue;
atom: TAtom;
begin
for model in ProteinModels do
for chain in model.Chains do
for residue in chain.Residues do
for atom in residue.Atoms do
begin
...
Чем то принципиально отличается?
← →
Kerk © (2011-07-02 12:31) [30]
> _Юрий (02.07.11 12:18) [29]
Это не паскаль, это delphi :)
Но в остальном ты прав.
← →
Думкин (с отпуска) (2011-07-02 17:05) [31]там точку не поставишь, чтобы выпадал список.
← →
eXAAAXe (2011-07-02 19:56) [32]with - хорошая штука, работать со структурами удобно.
И создавая объект, без экземпляра класса.
Только одно пожелание, при вложенных with не плохо бы видеть замечание, мол можно обратиться к одноименному элементу, что ухудшает читабельность.
← →
* © (2011-07-02 20:01) [33]
> И создавая объект, без экземпляра класса.
чо? о_О
← →
uw © (2011-07-02 21:02) [34]
with XMLDoc.DocumentElement do
begin
with AddChild("countries") do
begin
with AddChild("country") do
begin
Attributes["countryCode"] := "HN";
Attributes["nameRu"] := Гондурас";
Attributes["nameEn"] := Honduras";
AddChild("notes").NodeValue := "Прекрасное место для отдыха";
end;
with AddChild("country") do
begin
...
end;
...
end;
...
end;
← →
uw © (2011-07-02 21:13) [35]
with TXMLDocument.Create(TComponent.Create(nil)) do
try
...
finally
Owner.Free;
end;
← →
картман © (2011-07-02 21:32) [36]
> И создавая объект, без экземпляра класса.
до чего ж, однако, технологии дошли
> uw © (02.07.11 21:02) [34]
а это что - демонстрация оных?
← →
eXAAAXe (2011-07-02 21:44) [37]
> картман © (02.07.11 21:32) [36]
>
>
> > И создавая объект, без экземпляра класса.
>
> до чего ж, однако, технологии дошли
Имелось ввиду такое:
Экземпляр создается, но в вар не прописывается.
with TRegistry.Create do try
//читаем/пишем
finally
Free;
end;
← →
картман © (2011-07-02 22:53) [38]
> eXAAAXe (02.07.11 21:44) [37]
так это:
> Имелось ввиду такое:
> Экземпляр создается, но в вар не прописывается.
или то:
> И создавая объект, без экземпляра класса.
?
← →
eXAAAXe (2011-07-02 23:03) [39]
> картман © (02.07.11 22:53) [38]
> И создавая объект, без экземпляра класса + "прописанного в вар".
Надо дописать.
← →
jack128_ (2011-07-02 23:04) [40]
> Чем то принципиально отличается?
да. Сложностью реализации iterator паттерна на дельфи. Пока в дельфи не появится yield - не взлетит.
← →
TUser © (2011-07-03 06:02) [41]
> _Юрий (02.07.11 12:18) [29]
А это кто так умеет? (Я, каюсь, застрял на уровне Делфи 7)
← →
Юрий Зотов © (2011-07-03 09:29) [42]> cross (01.07.11 16:27)
> как вы относитесь к оператору with?
У нас одностороннее знакомство: я его знаю, он меня - нет.
> стоит ли его использовать?
Дело вкуса.
> хотелось бы услышать ваше мнение.
Я использую его в простых и коротких конструкциях, где он практически не влияет на читабельность. Иногда использую двойной with, но только там, где он наверняка не дает неоднозначности. И никогда - тройной и выше.
← →
_Юрий (2011-07-03 10:08) [43]
> jack128_ (02.07.11 23:04) [40]
> да. Сложностью реализации iterator паттерна на дельфи. Пока
> в дельфи не появится yield - не взлетит.
Не вижу особых проблем, так как в 99 процентах случаев это относится к списку, а для него уже все реализовано.
> TUser © (03.07.11 06:02) [41]
>
>
См. GetEnumerator
Не помню, с какой версии появился, но точно достаточно давно, возможно, что есть уже в D7
← →
DiamondShark © (2011-07-03 11:47) [44]
> jack128_ (02.07.11 23:04) [40]
> > Чем то принципиально отличается?
> да. Сложностью реализации
> iterator паттерна на дельфи. Пока в дельфи не появится yield
> - не взлетит.
В C# 1.0 yield не было, но итераторы как-то взлетали.
yield -- фигня.
Многие прогрессивные патерны не взлетят без автоматического управления памятью.
← →
DiamondShark © (2011-07-03 11:50) [45]
> _Юрий (02.07.11 12:18) [29]
Разумеется, не отличается. Все CLS-языки мало чем принципиально отличатся. Что и доказывает тезис о том, что дело не в with, а в совсем других языковых средствах, при наличии которых и with не особо-то и нужен.
← →
DiamondShark © (2011-07-03 12:01) [46]
> _Юрий (03.07.11 10:08) [43]
> Не вижу особых проблем,
class MyEnumerator : IEnumerator
{
MyElement m_Current;
object IEnumerator.Current
{
get { return m_Current; }
}
bool IEnumerator.MoveNext()
{
if (AnyExternalCondition)
m_Current = new MyElement();
else
return false;
return true;
}
}
А теперь вопрос: кто будет заниматься генерируемыми экземплярами в исполняющей среде без автоматического управления памятью?
← →
DiamondShark © (2011-07-03 12:04) [47]
> TUser © (03.07.11 06:02) [41]
> А это кто так умеет? (Я, каюсь, застрял на уровне Делфи 7)
С 2005 появилось.
← →
_Юрий (2011-07-03 13:15) [48]
> DiamondShark © (03.07.11 12:01) [46]
>
>
> А теперь вопрос: кто будет заниматься генерируемыми экземплярами
> в исполняющей среде без автоматического управления памятью?
Программист будет заниматься, какие варианты.
Можно поручить это итератору - запоминание предыдущего экземпляра, и его разрушение перед следущей итерацией, а последний разрушается вместе с самим итератором. Такой вариант у меня уже взлетел, просто пришлось подробно задокументировать поведение (разрушение или неразрушение идет в соответствии с переданным в конструктор итератора параметром). Слегка через задницу, но проблема решилась.
Впрочем, в большинстве случаев итерация не предполагает инстанцирования на кажлом шаге, и эта проблема не возникает вовсе.
ЗЫ, Если чего, я совершенно не отрицаю преимуществ, которые дает автоматическое управление памятью
← →
DiamondShark © (2011-07-03 14:07) [49]
> Впрочем, в большинстве случаев итерация не предполагает
В большинстве случаев, итерация (как, впрочем, вообще любая высокоуровневая конструкция) предполагает сокрытие деталей реализации.
У вас же все потроха наружу торчат.
Документируй, не документируй, а рано или поздно встретятся непонятно откуда взявшийся инстанс, про который есть только ссылка на интерфейс-енумератор и непонятно откуда взявшийся инстанс, про который есть только ссылка на интерфейс-консумер. И опачки.
Если вы реализуете интерфейс, то вы не имеете права требовать от клиента сакрального знания, сверх спецификации интерфейса.
← →
Дмитрий Тимохов (2011-07-03 20:18) [50]Иногда пользую. Но редко.
Лучше через однобуквенные лок. переменные.
← →
Kerk © (2011-07-03 20:45) [51]А почему однобуквенных-то? Символы экономишь? :)
Блин, не ветка, а сборник моих кошмаров :)
← →
Inovet © (2011-07-03 20:54) [52]> [51] Kerk © (03.07.11 20:45)
> А почему однобуквенных-то?
Остальные цифры
а1, а11, а111112
:)
← →
Дмитрий Тимохов (2011-07-03 21:11) [53]ну я оч. редко использую - очень. на 2млн строк написанных мною за жизь - места 3 всего...
← →
Игорь Шевченко © (2011-07-03 23:04) [54]
> на 2млн строк написанных мною за жизь
а как ты строки считаешь ?
← →
_Юрий (2011-07-03 23:13) [55]
> DiamondShark © (03.07.11 14:07) [49]
>
>
> В большинстве случаев, итерация (как, впрочем, вообще любая
> высокоуровневая конструкция) предполагает сокрытие деталей
> реализации.
Такая деталь, как "что же нам вернулось - новый инстанс, или уже существующий" - вовсе не то, от чего следует абстрагироваться, неважно в каком языке. Вызывающая сторона должна четко понимать, что же она получила. По крайней мере в случаях, когда полученный экземпляр поддерживает изменение состояния.
Все прочие детали реализации сокрыты одинаково в обоих примерах.
← →
Anatoly Podgoretsky © (2011-07-03 23:30) [56]> Игорь Шевченко (03.07.2011 23:04:54) [54]
1, 2, 3,...2 000 000
← →
Kerk © (2011-07-03 23:35) [57]
> _Юрий (03.07.11 23:13) [55]
> Такая деталь, как "что же нам вернулось - новый инстанс,
> или уже существующий" - вовсе не то, от чего следует абстрагироваться,
> неважно в каком языке. Вызывающая сторона должна четко
> понимать, что же она получила.
Принятие общего правила "я тебя породил, я тебя и убью" избавляет от подобной головной боли.
← →
Eraser © (2011-07-03 23:57) [58]> [54] Игорь Шевченко © (03.07.11 23:04)
кстати, имеется ли какая-нибудь удобная утилита для подсчета строк в pas-файлах? Понимаю, что написать можно и самому, но скорее всего ведь есть готовые средства с простенькой статистикой.
← →
Anatoly Podgoretsky © (2011-07-04 00:25) [59]> Eraser (03.07.2011 23:57:58) [58]
Посмотри у меня на сайте, в программах
← →
TUser © (2011-07-04 10:21) [60]cat *.pas *.dpr | wc -l
нужен цигвин или линукс
← →
DiamondShark © (2011-07-04 10:33) [61]
> Kerk © (03.07.11 23:35) [57]
> Принятие общего правила "я тебя породил, я тебя и убью"
> избавляет от подобной головной боли.
Но рождает головную боль типа: "Кого считать породителем?"
interface IResourceManager
{
Stream GetResourceStream(string resourceName);
}
Вопрос: кто "породил" стрим (а, следовательно, ответственнен за уничтожение), клиент, вызвавший GetResourceStream, или реализатор IResourceManager, который, собственно, и создал конкретный инстанс и вернул его как абстрактную ссылку клиенту?
← →
Anatoly Podgoretsky © (2011-07-04 10:59) [62]> DiamondShark (04.07.2011 10:33:01) [61]
Version Information
--------------------------------------------------------------------------------
..NET Framework
Supported in: 4, 3.5, 3.0
Ответственнен за уничтожение .NET
← →
oxffff © (2011-07-04 12:03) [63]
> Ответственнен за уничтожение .NET
:)))))))))))))
← →
Inovet © (2011-07-04 12:11) [64]> [63] oxffff © (04.07.11 12:03)
> > Ответственнен за уничтожение .NET
>
> :)))))))))))))
Джон Конар.
← →
oxffff © (2011-07-04 12:21) [65]
> Inovet © (04.07.11 12:11) [64]
:)
← →
Kerk © (2011-07-04 13:17) [66]
> DiamondShark © (04.07.11 10:33) [61]
>
>
> > Kerk © (03.07.11 23:35) [57]
> > Принятие общего правила "я тебя породил, я тебя и убью"
> > избавляет от подобной головной боли.
>
> Но рождает головную боль типа: "Кого считать породителем?
> "
>
> interface IResourceManager
> {
> Stream GetResourceStream(string resourceName);
> }
>
А чего тут думать-то? Надо просто правильно методы назвать.interface IResourceManager
{
Stream GetResourceStream(string resourceName);
Stream CreateResourceStream(string resourceName);
}
← →
Игорь Шевченко © (2011-07-04 14:53) [67]Eraser © (03.07.11 23:57) [58]
Я wc использую
← →
Anatoly Podgoretsky © (2011-07-04 16:06) [68]> Игорь Шевченко (04.07.2011 14:53:07) [67]
оо?
← →
Игорь Шевченко © (2011-07-04 17:08) [69]
> оо?
как в [60]
← →
_Юрий (2011-07-04 19:30) [70]
> Kerk © (03.07.11 23:35) [57]
> Принятие общего правила "я тебя породил, я тебя и убью"
> избавляет от подобной головной боли.
>
Это не всегда приемлимо. Например - стартуем короткую транзакцию, делаем выборку из базы, запоминаем список объектов, потом тут же закрывем транзакцию, а список оставляем себе.
В общем то, головной боли на самом деле никакой нет.
function TRepository.GetEnumerable<T>(AutoDestroyObjects: Boolean): IEnumerable<T>;
а дальше всего два варианта:
for MyModel in Repository.GetEnumerable<TMyModel>(True) do
//MyModel актуален только в течение итерации, указатель не запоминаем
for MyModel in Repository.GetEnumerable<TMyModel>(False) do
//необходимо запомнить указатель для дальнейшего разрушения
И все, никаких неоднозначностей.
← →
oxffff © (2011-07-04 19:36) [71]
> _Юрий (04.07.11 19:30) [70]
А в чем состоит задача?
← →
_Юрий (2011-07-04 20:53) [72]
> oxffff © (04.07.11 19:36) [71]
>
>
задача состоит в том, чтобы не запутаться с разрушением объектов в случае, когда итератор на каждом шаге порождает новый объект.
← →
Palladin © (2011-07-04 22:34) [73]
> _Юрий
выборка из базы и "запоминание" объектов и есть их порождение. несогласен?
← →
asail © (2011-07-04 23:02) [74]
> Eraser © (03.07.11 23:57) [58]
> кстати, имеется ли какая-нибудь удобная утилита для подсчета
> строк в pas-файлах?
CnWizards
← →
_Юрий (2011-07-04 23:26) [75]
> Palladin © (04.07.11 22:34) [73]
Из базы у нас возвращаются не объекты, а датасет. Порождением объектов приходится заниматься лично
← →
Kerk © (2011-07-04 23:36) [76]
> _Юрий (04.07.11 23:26) [75]
Ну и в чем проблема-то? Ты лично породил, ты лично и уничтожай.
← →
oxffff © (2011-07-05 09:13) [77]
> _Юрий (04.07.11 20:53) [72]
>
> > oxffff © (04.07.11 19:36) [71]
> >
> >
>
>
> задача состоит в том, чтобы не запутаться с разрушением
> объектов в случае, когда итератор на каждом шаге порождает
> новый объект.
А где путаница?
1. Например объект может предоставлять несколько енумераторов, по стратегии обхода, по стратегии принадлежности, т.е. параметр AutoDestroyObjects: Boolean не нужен.
2. Енумератор может освобождать объекты сам по окончанию своей работы.
3. Или может освобождать предыдущий объект после MoveNext на текущий.
4. GC
5. ....
← →
_Юрий (2011-07-05 20:21) [78]
> oxffff © (05.07.11 09:13) [77]
> А где путаница?
Я и говорю, что нет никакой путаницы. В ветке все написано, собственно.
Я просто рассказал о том, как сделал итератор, в ответ на
DiamondShark © (03.07.11 11:47) [44]
Многие прогрессивные патерны не взлетят без автоматического управления памятью.
Впрочем, утверждение в целом верное. Но итератор таки взлетел.
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2011.10.30;
Скачать: [xml.tar.bz2];
Память: 0.66 MB
Время: 0.005 c