You can do that something similar to that, sure.
But, you'd be implementing a class and doing an opIndexAssign. That's
totally different from just returning the associative array outright.
What you'd do to make a non-modifyable array is this:
class Foo(T)
{
private T[] data;
public ref T opIndex(int i)
{
return this.data[i];
}
/*
public ref T opIndexAssign(int i, T val)
{
// Do some sort of validation.
this.data[i] = val;
return this.data[i];
}
*/
}
But, maybe you want the associative array to be modifiable? For
example, I have an XPath library, and in it I just have a namespaces
member. I place no logic on this, so the interface to add namespaces is
as simple as modifying the associative array (e.g. .namespaces["xhtml"]
= "http://www.w3.org/1999/xhtml".)
You have the control to do either one. But, a member being private just
means the user of the class cannot access the member *though that method
or means*. It does not affect the data, it doesn't make it special or
non-modifiable, and it shouldn't.
As to your other question - there are good reasons for that. For
example, suppose I had a database class. If I have an instance of the
database connection as a member of the result class, I don't mind if you
modify the connection through that member variable.
However, if you were to reassign the member (e.g. = new DBConnection()),
that wouldn't make sense and could cause me serious problems. The
connection class can manage what parts of it you can modify or not, so
as long as I force you to use the one I already have, I'm safe.
-[Unknown]
Tyro[a.c.edwards] wrote:
On 5/3/2009 8:17 PM, Unknown W. Brackets wrote:
Well, if you really want a "protected" associative array, or array for
that matter, you probably should define a wrapper class that inlines the
access you're willing to allow.
From a basic perspective, _testMap is a structure of data. Although it
is private, there's no reason it can't be modified through an accessor.
Without a setter, the only thing that should fail is test.testMap =
something. Requiring a setter for any minor change makes no sense.
I was following until now... If I can modify said private member at a
whim, why on earth would I prevent this case? Is this because I would
be assigning it a completely new value vice simply modifying its
content? If that is the case, am I correct in saying that this
characteristic is applicable only to arrays?
Compare it to this: if you have a class that has a member object (e.g. a
User with a Socket member variable), should it be necessary to have a
setter to change the Socket? Can't the Socket handle its own
private/public-ness?
Arrays and associative arrays are the same, except that the members you
use are public.
-[Unknown]
Got you... I think I understand. That being the case though, wouldn't
it be just as useful to build the same "accessor" capability into
opAssign such that you can:
class Foo
{
private sometype _data;
public ref typeof(_data) opAssign() { return _data; }
}
Foo b = new foo;
b[0] = 1;
Why is it necessary to have a separate/different "accessor" function?
Tyro[a.c.edwards] wrote:
On 5/3/2009 6:25 PM, Unknown W. Brackets wrote:
This code works fine (D 2.x only):
class Test
{
private int[int] _testMap;
public ref int[int] testMap() {return _testMap;}
}
void main()
{
Test test = new Test();
test.testMap[0] = 1;
}
Note the "ref". Otherwise, a value is returned which is not modifiable.
This will also fix test.array.length. Nothing wrong here, no creepy bad
temporary property problems.
Is this an intended or even desirable "feature" of the language or
just something that happens to work in D 2.x? I ask because to the
untrained eye, it is unclear exactly what is happening. There is
nothing to inform me that _testMap can be modified from outside the
class. Even with "ref" there it doesn't make it any clearer.
Matter of fact, I just had a problem in Phobos 2 where a function was
defined like that and I had to comment out the "ref" for it to work.
Kept telling me that some array was not an lvalue. The minute I
commented out the "ref", everything worked like a charm.
Also it makes more sense to me to have separate functions as getters
and setters. Maybe that's only because I lacking proper training in
the art of computer programming though.
I suppose you could also try returning a pointer to an associative
array
(e.g. with &) in D 1.x.
-[Unknown]
flourish wrote:
Hi,
why does the following code not compile -- or how to declare a
(usable)
property of an associative array field?
//////////////////////
class Test
{
private int[int] _testMap;
public int[int] testMap() {return _testMap;}
}
void main()
{
Test test = new Test();
test.testMap[0] = 1;
}
/////////////////
*** Error: test.testMap() is not an lvalue
Regards,
flourish