www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is it possible to elegantly craft a class that can be used as shared

reply "Gary Willoughby" <dev nomad.so> writes:
Is it possible to elegantly craft a class that can be used as 
shared and as normal?

I have a class which functions fine when instantiated as normal 
but i want to enable it for use for shared objects.

     auto t = T();
     auto t = shared(T)();  //<--- like this.

Then i have the problem that a shared object can not call non 
shared methods. The only solution i can see is to have multiple 
overloads of the class' methods to handle being shared, like this:

class T
{
     public void Foo() {...}
     public shared void Foo() {...}
}

Is this the right way of going about this? The reason i ask is 
that both methods have exactly the same code and to avoid 
duplication i'm using mixins for each method body, yuk! help?
Mar 02 2014
parent reply "Dicebot" <public dicebot.lv> writes:
shared and non-shared entities have different implementation. You 
unlikely want to have one for both.
Mar 02 2014
parent reply "Gary Willoughby" <dev nomad.so> writes:
On Sunday, 2 March 2014 at 18:04:06 UTC, Dicebot wrote:
 shared and non-shared entities have different implementation. 
 You unlikely want to have one for both.
It's part of my unit-testing toolkit that handles mocking of objects. I want to use the same code to handle shared and non-shared entities.
Mar 02 2014
parent reply "Tolga Cakiroglu" <tcak pcak.com> writes:
On Sunday, 2 March 2014 at 20:16:42 UTC, Gary Willoughby wrote:
 On Sunday, 2 March 2014 at 18:04:06 UTC, Dicebot wrote:
 shared and non-shared entities have different implementation. 
 You unlikely want to have one for both.
It's part of my unit-testing toolkit that handles mocking of objects. I want to use the same code to handle shared and non-shared entities.
I didn't like this feature as well, though after a while, you start getting used to it. Anyway, defining all methods as shared, using `cast()` when you don't want to use it as non-shared can be the best option for you I think. I discovered that `cast()` recently, and was writing whole class name all times.
Mar 02 2014
parent reply "Gary Willoughby" <dev nomad.so> writes:
On Sunday, 2 March 2014 at 20:23:26 UTC, Tolga Cakiroglu wrote:
 On Sunday, 2 March 2014 at 20:16:42 UTC, Gary Willoughby wrote:
 On Sunday, 2 March 2014 at 18:04:06 UTC, Dicebot wrote:
 shared and non-shared entities have different implementation. 
 You unlikely want to have one for both.
It's part of my unit-testing toolkit that handles mocking of objects. I want to use the same code to handle shared and non-shared entities.
I didn't like this feature as well, though after a while, you start getting used to it. Anyway, defining all methods as shared, using `cast()` when you don't want to use it as non-shared can be the best option for you I think. I discovered that `cast()` recently, and was writing whole class name all times.
Have you got a small example?
Mar 02 2014
parent reply "Tolga Cakiroglu" <tcak pcak.com> writes:
 Have you got a small example?
import std.stdio; class Test{ private int number; public void setNumber( int newValue ) shared{ number = newValue; } public int getNumber() shared{ return number; } } void main(){ auto test = new Test(); (cast(shared)test).setNumber( 5 ); writeln("Value = ", (cast(shared)test).getNumber() ); } But do not forget the fact that because of the object `test` is not shared, therefore the attribute `number` is not shared. Thus, this will not be working multi-threded.
Mar 03 2014
parent reply "Gary Willoughby" <dev nomad.so> writes:
On Monday, 3 March 2014 at 12:07:15 UTC, Tolga Cakiroglu wrote:
 Have you got a small example?
import std.stdio; class Test{ private int number; public void setNumber( int newValue ) shared{ number = newValue; } public int getNumber() shared{ return number; } } void main(){ auto test = new Test(); (cast(shared)test).setNumber( 5 ); writeln("Value = ", (cast(shared)test).getNumber() ); } But do not forget the fact that because of the object `test` is not shared, therefore the attribute `number` is not shared. Thus, this will not be working multi-threded.
I still don't understand this example. To be more clear lets take the following class: class Test { private int number; public void setNumber(int newValue) { number = newValue; } public int getNumber() { return number; } } I need to instantiate that class twice like this: auto a = new Test(); auto b = new shared Test(); And be able to use the methods of 'a' and 'b' without an error. How can i do this without overloading the methods is the big question. Casting the object is not an option in my particular use case.
Mar 03 2014
parent "Stanislav Blinov" <stanislav.blinov gmail.com> writes:
On Monday, 3 March 2014 at 16:42:10 UTC, Gary Willoughby wrote:

 class Test
 {
 	private int number;

 	public void setNumber(int newValue)
 	{
 		number = newValue;
 	}

 	public int getNumber()
 	{
 		return number;
 	}
 }

 I need to instantiate that class twice like this:

 auto a = new Test();
 auto b = new shared Test();

 And be able to use the methods of 'a' and 'b' without an error. 
 How can i do this without overloading the methods is the big 
 question. Casting the object is not an option in my particular 
 use case.
You can't and you shouldn't be able to. Why are you so inclined on subverting the type system? If you're sharing an instance that doesn't support 'shared', then you're providing thread-safety mechanisms (i.e. synchronization) and cast away shared. If you're sharing an instance that does support 'shared', it should provide its own thread-safety mechanisms (that you shouldn't care about beyond documentation). Note that even using plain operators on shared *scalars* is disallowed (though not yet implemented, https://d.puremagic.com/issues/show_bug.cgi?id=3672). Because implementation of those operators on shared variables is supposed to be different (i.e. atomicOp). The same goes for classes and structs too: 'void method()' and 'void method() shared' can't be expected to have the same implementation (and wouldn't). Were it different, there would be no sense in explicit sharing.
Mar 03 2014