With statement become like C#'s using?

Gambler fake at feather.org.ru
Mon Aug 5 13:50:49 PDT 2013


On 8/5/2013 11:30 AM, Bosak wrote:
> On Monday, 5 August 2013 at 13:54:38 UTC, Adam D. Ruppe wrote:
>> On Monday, 5 August 2013 at 13:42:01 UTC, Michal Minich wrote:
>>> But what Bosak proposes is that when "with" statements ends, the
>>> object should be destructed
>>
>> That would happen if the object is a struct, or wrapped in a struct,
>> since it would go out of scope at the end of the with and call its
>> destructor then.
>>
>> So then you could just go
>>
>> import std.typecons;
>> with(auto a = Scoped!T()) { ... }
>>
>> and the Scoped destructor does the deleting.
> 
> Exactly. My idea is to add third use case of with. Not there are 2 ways
> to use with(of witch I know):
> 
> 1) Declare something and use with to not repeat yourself:
> auto foo = new Foo;
> with(foo) {
>    name = "bar"; //foo.name = "bar";
> }
> In this case it is only used for object construction and setup. And the
> with statement doesn't destruct the object or anything like that.
> 2) Used with types
> struct Foo {
>     static int bar = 2;
> }
> with(Foo) {
>     bar++; //Foo.bar++;
> }
> Again with doesn't destruct or anything
> 
> All of the above are currently available, but I want a third case to be
> added:
> 
> 3) Used when you declare something in the with statement with scope only
> in the with statement
> with(Foo foo = new Foo) {
>     name = "bar";
> }
> After that foo's destructor gets called and since foo was in the scope
> of with it goes out of scope and no references are made to foo. There
> should be a constraint that you cannot take the address of foo in the
> with statement(i.e assign a global to foo)
> 3.1) Or used with rvalues??
> int[] values;
> with(new Foo) {
>     name = "bar";
>     values = getData(); //foo.getData()
> }
> //use values taken from foo
> 
> I think that in case 3.1 it is very intuitive for using resources like
> files. Instead of writing something like:
> string text;
> auto file = open("myfile.txt", "r");
> text = t.readlines();
> file.close();
> You can write this:
> string text;
> with(open("myfile.txt", "r")) { //no need to declare variable
>     text = readlines(); //just use the file to get the data
> }//with automaticaly calls close() on the file, even if exception got
> thrown
> And if the exception got thrown in the declaration of the with block,
> then the with block doesn't execute. For example in the above code if
> the file didn't exist, an exception would be thrown from open and no
> variable would be created.
> 
> I hope that I have made my suggestion more clear.

IMO, using statements in C# are annoying. They make otherwise linear
code much harder to read. The *idea* behind them makes total sense, but
I dislike the implementation. Instead of writing this:

public string[] GetLines(string name)
{
    string result;
    using (var file = new File(name))
    {
        result = file.ReadText();
    }
    return result.split('\n');
}

...I would very much like to write this:

public string[] GetLines(string name)
{
    autodispose var file = new File(name1);
    string result = file.ReadText(); //file disposed after this line,
since it's the last place it's used
    return result.split('\n');
}

Another problem with C#'s using (){} is that it doesn't easily scale
from single-method use to object-wide use. For example, would you want
to add "using" statements to every single method in a controller just
because all of them use the same database object?


More information about the Digitalmars-d mailing list