May 23, 2016 Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself? | ||||
---|---|---|---|---|
| ||||
Posted in reply to dan | On Saturday, 21 May 2016 at 17:32:47 UTC, dan wrote:
> (This effect could be simulated by making my_var into a function, but i don't want to do that.)
May I ask why you don't want to do that ?
In D you can call a function without args without ().
So if you write
private int my_var_ = 4; // where 4 is the default initialization value
@property int my_var1() { return my_var_; }
final int my_var2() { return my_var_; }
int my_var3() { return my_var_; }
int x = obj.my_var1;
x = obj.my_var2;
x = obj.my_var3;
my_var3 is virtual so I guess you get the overhead of a virtual method call which is probably not what you want.
my_var2 can't be overriden and if it doesn't itself override a method with a same name in a base class the compiler may optimize its call by inlining it. It's like a static method with 'this' passed as argument.
I'm not fully sure about my_var1. I'm still a beginner, but I think the compiler will optimize it into inlined instruction if it can as for my_var2.
Making the user accessing the member variables directly may look like it's more efficient, but it's bad API design because you can't change the class implementation affecting my_var_ without breaking the API. The D way enforces good programming and API design and optimizes as much as possible.
|
May 24, 2016 Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | On Monday, 23 May 2016 at 07:03:08 UTC, chmike wrote:
> On Saturday, 21 May 2016 at 17:32:47 UTC, dan wrote:
>
>> (This effect could be simulated by making my_var into a function, but i don't want to do that.)
>
> May I ask why you don't want to do that ?
>
> In D you can call a function without args without ().
>
> So if you write
>
> private int my_var_ = 4; // where 4 is the default initialization value
> @property int my_var1() { return my_var_; }
> final int my_var2() { return my_var_; }
> int my_var3() { return my_var_; }
>
> int x = obj.my_var1;
> x = obj.my_var2;
> x = obj.my_var3;
>
>
> my_var3 is virtual so I guess you get the overhead of a virtual method call which is probably not what you want.
>
> my_var2 can't be overriden and if it doesn't itself override a method with a same name in a base class the compiler may optimize its call by inlining it. It's like a static method with 'this' passed as argument.
>
> I'm not fully sure about my_var1. I'm still a beginner, but I think the compiler will optimize it into inlined instruction if it can as for my_var2.
>
> Making the user accessing the member variables directly may look like it's more efficient, but it's bad API design because you can't change the class implementation affecting my_var_ without breaking the API. The D way enforces good programming and API design and optimizes as much as possible.
Thanks Ch Mike for your reply and explanation, and the
further information about calling functions.
Thanks also to the other Mike, to Daniel for the interesting
union technique, and to Meta for further elaboration.
Daniel's union technique is pretty close to what i was
asking for.
Now, since you explicitly ask me 'why you don't
want to do that', i should answer. But my answer
won't be nearly as good as your analysis and
explanation, nor as good as any of the other replies. :(
Just aesthetically, i'd like to refer to the
variable within the class and outside the class
with exactly the same symbol.
But with all the ideas presented in the prior
discussion, i can get pretty close so it would
be a ridiculous point for me to complain about.
Thanks again for your help!
dan
|
May 24, 2016 Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself? | ||||
---|---|---|---|---|
| ||||
Posted in reply to dan | On 5/21/16 1:32 PM, dan wrote:
> Is it possible to have a class which has a variable which can be seen
> from the outside, but which can only be modified from the inside?
>
> Something like:
>
> class C {
> int my_var = 3; // semi_const??
> void do_something() { my_var = 4; }
> }
>
> And then in another file
>
> auto c = new C();
> c.my_var = 5; // <<<- should trigger a compile-time error
> writeln("the value is ", c.my_var); // <<<- should print 3
> c.do_something();
> writeln("the value is ", c.my_var); // <<<- should print 4
>
> Reading Alexandrescu's book suggests the answer is "no" (the only
> relevant type qualifiers are private, package, protected, public, and
> export, and none seem appropriate).
>
> (This effect could be simulated by making my_var into a function, but i
> don't want to do that.)
>
> TIA for any info!
A while ago, I discovered that this works.
class C {
union
{
private int _my_var;
public const int my_var;
}
void do_something() { _my_var = 4; }
}
-Steve
|
May 24, 2016 Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Tuesday, May 24, 2016 10:10:16 Steven Schveighoffer via Digitalmars-d-learn wrote:
> A while ago, I discovered that this works.
>
> class C {
> union
> {
> private int _my_var;
> public const int my_var;
> }
> void do_something() { _my_var = 4; }
> }
Yeah. That's basically what Rebindable does, though in its case, it's not really allowing you to mutate any data, just what the reference refers to. Regardless, it does seem like a hole in the type system.
- Jonathan M Davis
|
May 24, 2016 Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Tuesday, 24 May 2016 at 15:07:55 UTC, Jonathan M Davis wrote:
> On Tuesday, May 24, 2016 10:10:16 Steven Schveighoffer via Digitalmars-d-learn wrote:
>> A while ago, I discovered that this works.
>>
>> class C {
>> union
>> {
>> private int _my_var;
>> public const int my_var;
>> }
>> void do_something() { _my_var = 4; }
>> }
>
> Yeah. That's basically what Rebindable does, though in its case, it's not really allowing you to mutate any data, just what the reference refers to. Regardless, it does seem like a hole in the type system.
>
> - Jonathan M Davis
I don't believe so. H. S. Teoh recently fixed a definite bug when you have something like:
struct S
{
union
{
int n1;
immutable int n2;
}
}
But I'm pretty sure the case where n2 is const was purposely not fixed as it doesn't break the type system. The value of a const variable can be changed at any time out from under you, so a union of a mutable and const int does not break any type system guarantees.
|
May 24, 2016 Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Tuesday, May 24, 2016 18:28:44 Meta via Digitalmars-d-learn wrote:
> On Tuesday, 24 May 2016 at 15:07:55 UTC, Jonathan M Davis wrote:
> > On Tuesday, May 24, 2016 10:10:16 Steven Schveighoffer via
> >
> > Digitalmars-d-learn wrote:
> >> A while ago, I discovered that this works.
> >>
> >> class C {
> >>
> >> union
> >> {
> >>
> >> private int _my_var;
> >> public const int my_var;
> >>
> >> }
> >> void do_something() { _my_var = 4; }
> >>
> >> }
> >
> > Yeah. That's basically what Rebindable does, though in its case, it's not really allowing you to mutate any data, just what the reference refers to. Regardless, it does seem like a hole in the type system.
> >
> > - Jonathan M Davis
>
> I don't believe so. H. S. Teoh recently fixed a definite bug when you have something like:
>
> struct S
> {
> union
> {
> int n1;
> immutable int n2;
> }
> }
>
> But I'm pretty sure the case where n2 is const was purposely not fixed as it doesn't break the type system. The value of a const variable can be changed at any time out from under you, so a union of a mutable and const int does not break any type system guarantees.
Except that int is a _value_ type, not a reference type. So, unions aside, once you've declared
const foo = 42;
it's impossible for the value of foo to change, and there's no real difference between
const foo = 42;
and
immutable foo = 42;
typeof(foo) will give you const in one case and immutable in the other, but effectively, they're identical.
- Jonathan M Davis
|
May 25, 2016 Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 5/24/16 6:47 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
> On Tuesday, May 24, 2016 18:28:44 Meta via Digitalmars-d-learn wrote:
>> On Tuesday, 24 May 2016 at 15:07:55 UTC, Jonathan M Davis wrote:
>>> On Tuesday, May 24, 2016 10:10:16 Steven Schveighoffer via
>>>
>>> Digitalmars-d-learn wrote:
>>>> A while ago, I discovered that this works.
>>>>
>>>> class C {
>>>>
>>>> union
>>>> {
>>>>
>>>> private int _my_var;
>>>> public const int my_var;
>>>>
>>>> }
>>>> void do_something() { _my_var = 4; }
>>>>
>>>> }
>>>
>>> Yeah. That's basically what Rebindable does, though in its
>>> case, it's not really allowing you to mutate any data, just
>>> what the reference refers to. Regardless, it does seem like a
>>> hole in the type system.
>>>
>>> - Jonathan M Davis
>>
>> I don't believe so. H. S. Teoh recently fixed a definite bug when
>> you have something like:
>>
>> struct S
>> {
>> union
>> {
>> int n1;
>> immutable int n2;
>> }
>> }
>>
>> But I'm pretty sure the case where n2 is const was purposely not
>> fixed as it doesn't break the type system. The value of a const
>> variable can be changed at any time out from under you, so a
>> union of a mutable and const int does not break any type system
>> guarantees.
>
> Except that int is a _value_ type, not a reference type. So, unions aside,
> once you've declared
>
> const foo = 42;
>
> it's impossible for the value of foo to change, and there's no real
> difference between
>
> const foo = 42;
>
> and
>
> immutable foo = 42;
>
> typeof(foo) will give you const in one case and immutable in the other, but
> effectively, they're identical.
But this isn't that. That's a declaration with an initializer.
There is a difference between:
struct S
{
const foo = 42;
}
and
struct S
{
const int foo;
}
-Steve
|
Copyright © 1999-2021 by the D Language Foundation