Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-27 Thread via Digitalmars-d-learn
On Friday, 26 September 2014 at 18:18:45 UTC, Steven 
Schveighoffer wrote:
On 9/26/14 1:36 PM, Marc =?UTF-8?B?U2Now7x0eiI=?= 
schue...@gmx.net wrote:


Alternatively, you could create a union with a private and a 
public
member with the same types, but I wouldn't recommend it. 
Besides, the

members would need to have different names:

class Foo {
union {
private int a;
public int b;
}
}


Hm.. that doesn't provide readonly access to either a or b.

But it gave me an idea:

class Foo {
   union {
  private int _a;
  public const int a;
   }
   void setA(int x) { _a = x; }
}



Yes, that's what I originally intended. Just forgot the const, 
and didn't even notice it after I reread it :-P


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-27 Thread AsmMan via Digitalmars-d-learn
On Friday, 26 September 2014 at 18:18:45 UTC, Steven 
Schveighoffer wrote:
On 9/26/14 1:36 PM, Marc =?UTF-8?B?U2Now7x0eiI=?= 
schue...@gmx.net wrote:


Alternatively, you could create a union with a private and a 
public
member with the same types, but I wouldn't recommend it. 
Besides, the

members would need to have different names:

class Foo {
union {
private int a;
public int b;
}
}


Hm.. that doesn't provide readonly access to either a or b.

But it gave me an idea:

class Foo {
   union {
  private int _a;
  public const int a;
   }
   void setA(int x) { _a = x; }
}

Hot damn! It works too :) Can't access _a from outside the 
module, can access a, but can't write it (even from within 
Foo). It's like an auto-inlined property function.


I don't know how it would affect the optimizer, or the GC 
scanner. Unions are ugly things...


-Steve


This is really a loot cool and works. Thanks. If private in D had 
same behavior like in C#/C++, ie, private to scope of where class 
was declared and not public to the entire module, I guess we 
could even do:


class Foo {
union {
private int a_;

public @property int a() {
return a_;
}

private @property void a(int value) {
a_ = value;
}
}

//no one need knows the 'a_' (ugly?) identifier
void setValue(int x)
{
a = x;
}
}

And then

Foo f = new Foo();
f.a = 10; // give a compile error becaus it is private and 
acessible within Foo class only


BTW: I'm not sure about memory usage where using properties. But 
it is still cool.


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/27/14 5:48 AM, Marc =?UTF-8?B?U2Now7x0eiI=?= schue...@gmx.net

Yes, that's what I originally intended. Just forgot the const, and
didn't even notice it after I reread it :-P


I wondered... ;)

-Steve


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread Gary Willoughby via Digitalmars-d-learn

On Friday, 26 September 2014 at 17:16:04 UTC, AsmMan wrote:
I know I can combine it by making an extra variable plus a 
property like this:


class Foo
{
  private int a_;

  void do_something1()
  {
a_ = baa();
  }

  void do_something2()
  {
if(cond) a_ = baa2();
  }

  @property int a()
  {
  return a;
   }
}

This is the C#'s to do which I'm translated to D within my 
limited knowledge. I don't do much OOP, maybe it's possible and 
I don't know. I'm using @property to make 'a' accessible and 
readonly at same time but I wanted to do that without this a_ 
extra variable, i.e, only the methods within the Foo class can 
assign a new value to a but a instance of Foo can't. An 
imaginary code example:


class Foo
{
  public MAGIC_HERE int a;

  void do_something1()
  {
a = baa();
  }

  void do_something2()
  {
if(cond) a = baa2();
  }
}


And then:

Foo f = new Foo();
writeln(f.a); // output value of a
f.a = 10; // compile error: a is readonly outside Foo's methods.

I hope it's clear (sorry for por English)


I think the extra variable and the properties are the way to go 
and it's the idiomatic way. In fact that's the reason properties 
are there.


Saying that though, you can achieve what you want implementing a 
little more code using opDispatch. opDispatch intercepts calls to 
undefined members and deals with them, in this case forwarding to 
a private variable.


http://dlang.org/operatoroverloading.html#dispatch


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread Ali Çehreli via Digitalmars-d-learn

On 09/26/2014 10:16 AM, AsmMan wrote:

 I know I can combine it by making an extra variable plus a property like
 this:

That's the proper way of doing it in D.

If it's too much work, it is possible to take advantage of mixins to 
reduce the boilerplate. I found the following code among my D samples; 
it must have been found on these forums.


Defining without set would disallow the setter:

alias AutoImplementedProperty!(string, get) title;

The code:

import std.stdio;

class Bar
{
alias AutoImplementedProperty!(string, get, set) title;
}

template AutoImplementedProperty(T, args...)
{
import std.typetuple;
@property
{
private T _name;
static if (args.length)
{
static if (staticIndexOf!(get, args)  -1)
{
public T AutoImplementedProperty()
{
return _name;
}
}

static if (staticIndexOf!(set, args)  -1)
{
public void AutoImplementedProperty(T value)
{
_name = value;
}
}

}
}
}

void main(string[] args)
{
Bar a = new Bar();
a.title = asf;
writeln(a.title);

return;
}

 I wanted to do that without this a_ extra variable

If the value is set only once and it is known during construction, it is 
indeed mark the variable public const:


import std.stdio;

class Foo
{
public const int a;

this (int x)
{
a = 2 * x;
}
}

void main()
{
Foo f = new Foo(21);
writeln(f.a); // output value of a

Foo f2 = f;// copy works
f2 = f;// assignment works

// f.a = 10; // compile error: a is readonly outside Foo's methods.
}

Ali



Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread via Digitalmars-d-learn

On Friday, 26 September 2014 at 17:16:04 UTC, AsmMan wrote:
I know I can combine it by making an extra variable plus a 
property like this:


class Foo
{
  private int a_;

  void do_something1()
  {
a_ = baa();
  }

  void do_something2()
  {
if(cond) a_ = baa2();
  }

  @property int a()
  {
  return a;
   }
}

This is the C#'s to do which I'm translated to D within my 
limited knowledge. I don't do much OOP, maybe it's possible and 
I don't know. I'm using @property to make 'a' accessible and 
readonly at same time but I wanted to do that without this a_ 
extra variable, i.e, only the methods within the Foo class can 
assign a new value to a but a instance of Foo can't. An 
imaginary code example:


class Foo
{
  public MAGIC_HERE int a;

  void do_something1()
  {
a = baa();
  }

  void do_something2()
  {
if(cond) a = baa2();
  }
}


And then:

Foo f = new Foo();
writeln(f.a); // output value of a
f.a = 10; // compile error: a is readonly outside Foo's methods.

I hope it's clear (sorry for por English)


The closest you can get is probably this:

class Foo {
private int a_;

@property int a() {
return a_;
}

private @property void a(int value) {
a_ = value;
}
}

You can then assign to `a` inside the class `Foo` _and_ inside 
its module (because `private` is always accessible from within 
the same module), while from other modules, it can only be read.


But it's not exactly a read-only variable, because you cannot 
take an address from it, for example.


Alternatively, you could create a union with a private and a 
public member with the same types, but I wouldn't recommend it. 
Besides, the members would need to have different names:


class Foo {
union {
private int a;
public int b;
}
}


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread bearophile via Digitalmars-d-learn

Marc Schütz:

Alternatively, you could create a union with a private and a 
public member with the same types, but I wouldn't recommend it. 
Besides, the members would need to have different names:


class Foo {
union {
private int a;
public int b;
}
}


You can call them a and a_. Why are you not recommending this 
solution? It looks cool (if it works).


Bye,
bearophile


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread via Digitalmars-d-learn

On Friday, 26 September 2014 at 17:52:58 UTC, bearophile wrote:

Marc Schütz:

Alternatively, you could create a union with a private and a 
public member with the same types, but I wouldn't recommend 
it. Besides, the members would need to have different names:


   class Foo {
   union {
   private int a;
   public int b;
   }
   }


You can call them a and a_. Why are you not recommending this 
solution? It looks cool (if it works).


Don't know, it feels hacky. And I really don't like the two 
different names, what's the point if I have to distinguish the 
two manually?


Now yet another way came to my mind:

struct PrivatelyWritableProperty(T) {
private T value_;
const(T) get() const { return value_; }
private void opAssign(T value) { value_ = value; }
alias get this;
}

class Foo {
PrivatelyWritableProperty!int a;
}

But this looks even more fragile; there are probably some 
corner-cases where it doesn't work (for example, what happens 
when someone copies the containing struct?).


Re: Can I make a variable public and readonly (outside where was declared) at same time?

2014-09-26 Thread Steven Schveighoffer via Digitalmars-d-learn
On 9/26/14 1:36 PM, Marc =?UTF-8?B?U2Now7x0eiI=?= schue...@gmx.net 
wrote:



Alternatively, you could create a union with a private and a public
member with the same types, but I wouldn't recommend it. Besides, the
members would need to have different names:

 class Foo {
 union {
 private int a;
 public int b;
 }
 }


Hm.. that doesn't provide readonly access to either a or b.

But it gave me an idea:

class Foo {
   union {
  private int _a;
  public const int a;
   }
   void setA(int x) { _a = x; }
}

Hot damn! It works too :) Can't access _a from outside the module, can 
access a, but can't write it (even from within Foo). It's like an 
auto-inlined property function.


I don't know how it would affect the optimizer, or the GC scanner. 
Unions are ugly things...


-Steve