"Walter Bright" <newshou...@digitalmars.com> wrote in message news:hujd7m$11g...@digitalmars.com... > Adam Ruppe wrote: >> That sucks hard. I prefer it to finally{} though, since finally >> doesn't scale as well in code complexity (it'd do fine in this case, >> but not if there were nested transactions), but both suck compared to >> the scalable, beautiful, and *correct* elegance of D's scope guards. > > I agree. D's scope statement looks fairly innocuous and one can easily > pass it by with "blah, blah, another statement, blah, blah" but the more I > use it the more I realize it is a > > game changer > > in how one writes code. For example, here's the D1 implementation of > std.file.read: > > ------------------------------------------------------------- > /******************************************** > * Read file name[], return array of bytes read. > * Throws: > * FileException on error. > */ > > void[] read(char[] name) > { > DWORD numread; > HANDLE h; > > if (useWfuncs) > { > wchar* namez = std.utf.toUTF16z(name); > h = > CreateFileW(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, > FILE_ATTRIBUTE_NORMAL | > FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > } > else > { > char* namez = toMBSz(name); > h = > CreateFileA(namez,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING, > FILE_ATTRIBUTE_NORMAL | > FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null); > } > > if (h == INVALID_HANDLE_VALUE) > goto err1; > > auto size = GetFileSize(h, null); > if (size == INVALID_FILE_SIZE) > goto err2; > > auto buf = std.gc.malloc(size); > if (buf) > std.gc.hasNoPointers(buf.ptr); > > if (ReadFile(h,buf.ptr,size,&numread,null) != 1) > goto err2; > > if (numread != size) > goto err2; > > if (!CloseHandle(h)) > goto err; > > return buf[0 .. size]; > > err2: > CloseHandle(h); > err: > delete buf; > err1: > throw new FileException(name, GetLastError()); > } > ---------------------------------------------------------- >
Looking at that, if I didn't know better, I would think you were a VB programmer ;)