January 02, 2015 Re: How to create instance of class that get data from 2 another instance? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Suliman | class parseConfig { string dbname; string dbuser; string dbpass; string dbhost; string dbport; uint status; this() { auto checkLinkCode(string link) // we need to check all links to be sure if they are alive { .... return status; } ............. if (checkLinkCode(emsc_csem) == 200) { auto seismodownload = new seismoDownload(emsc_csem, this); //here seismodownload.parse(); } } } I know that in С# I can pass to function, and this would be point of class from where it's call (Here is parseConfig). Is it's possible to do something similar in D? |
January 02, 2015 Re: How to create instance of class that get data from 2 another instance? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Suliman | Oh mama mia! I did it! http://www.everfall.com/paste/id.php?a5pp73ns1e4k auto seismodownload = new seismoDownload(emsc_csem, this); then: auto mysql = new MySQL(parseconfig,eqs); So could anybody show me better way? As I said I did not fully understand how use global class instance... |
January 04, 2015 Re: How to create instance of class that get data from 2 another instance? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Suliman | On 01/02/2015 12:42 PM, Suliman wrote: > auto seismodownload = new seismoDownload(emsc_csem, this); > then: > auto mysql = new MySQL(parseconfig,eqs); > > So could anybody show me better way? Yes, there is a better way. > As I said I did not fully understand how use global class instance... One good thing about D is that globals are better than other languages because they are actually module-global and by default thread-local. Module-global means that there more than one module can use the same name for their respective globals; thread-local means that implicit data-sharing is prevented. However, module-globals can be harmful as well because depending on the design, they prevent functions from being reentrant and prevent having more than one of that resource. For that reason, it is usually better to provide the resource to its consumers e.g. as constructor parameters. Instead of this: string fileName; // <-- May be a problem static this() { /* Just to assume that we need a run time value. */ import std.random; import std.string; fileName = format("file_%s", uniform(0, 1000)); } struct S { void foo() { /* Assume that it uses fileName. It would be at least * confusing if there were more than one instance of * S. Which one would be using fileName when? */ } } void main() { auto s = S(); s.foo(); } Prefer this: struct S { string fileName; // <-- Takes it as a run-time argument // (Could be constructor parameter as well.) void foo() { /* Now it would be using its own fileName, which might * be provided to more than one object but then it * might be acceptable, presumably because it was * according to design. */ } } void main() { import std.random; import std.string; auto s = S(format("file_%s", uniform(0, 1000))); s.foo(); } Ali |
January 04, 2015 Re: How to create instance of class that get data from 2 another instance? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ali, thanks for example, I understood it, but I am still can't understand how to write code above without passing this as parameter... |
January 04, 2015 Re: How to create instance of class that get data from 2 another instance? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Suliman | On Sunday, 4 January 2015 at 15:37:53 UTC, Suliman wrote:
> Ali, thanks for example, I understood it, but I am still can't understand how to write code above without passing this as parameter...
But now I think that possible is mess architecture of app if I meet such problem...
|
January 05, 2015 Re: How to create instance of class that get data from 2 another instance? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Suliman | On 01/04/2015 07:37 AM, Suliman wrote: > how to write code above without passing this as parameter... For reference, here is your code: http://www.everfall.com/paste/id.php?a5pp73ns1e4k There is nothing fundamentally wrong in a class constructor passing 'this' to an object that it constructs: class A { B b; this() { b = new B(this); // Makes its B } } However, keep in mind that 'this' is not an A until we leave the constructor. For that reason, the B's constructor must not use the A reference that it receives. In that code, apparently A owns a B for its purposes. Presumably, that is why A's constructor is creating a B object. Commonly, it is either not the case or even if so, we want to provide a B from "above" so that A becomes testable. (Search for "parametrize from above" by "kevlin henney"; or search for "dependency injection".) So, usually the following idiom is prefered: class A { B b; this(B b) { this.b = b; // Takes its B as a parameter } } Well, it works fine until you need both of the objects to refer to each other: class A { B b; this(B b) { this.b = b; } } class B { A a; this(A a) { this.a = a; } } It is impossible to construct two objects at the same, which refer to each other: auto a = new A(/* where is my B? */); // Oops! auto b = new B(a); So, A must not have an invariant that requires non-null B and that it must have a property to set the B later on: auto a = new A(null); // Here, A must be happy with null B auto b = new B(a); a.b = b; // Finally, we have two happy objects So, your code is just fine because there is no general solution anyway. Ali |
Copyright © 1999-2021 by the D Language Foundation