Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
June 24, 2016 Get calling this, if exists | ||||
---|---|---|---|---|
| ||||
Is there a type of __THIS__ construct similar to __FILE__ and __LINE__? Something that returns the current this ptr if it exists, null otherwise. Log(string filename = __FILE__, Object obj = __THIS__)() { // inspect obj and do stuff } |
June 24, 2016 Re: Get calling this, if exists | ||||
---|---|---|---|---|
| ||||
Posted in reply to "Smoke" Adams | On Friday, 24 June 2016 at 02:57:28 UTC, "Smoke" Adams wrote:
> Is there a type of __THIS__ construct similar to __FILE__ and __LINE__?
>
> Something that returns the current this ptr if it exists, null otherwise.
>
> Log(string filename = __FILE__, Object obj = __THIS__)()
> {
> // inspect obj and do stuff
> }
There is no 'this' pointer unless you are calling a member function on an aggregate, so you can never have one that is null.
|
June 24, 2016 Re: Get calling this, if exists | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On Friday, 24 June 2016 at 03:04:25 UTC, Mike Parker wrote:
> On Friday, 24 June 2016 at 02:57:28 UTC, "Smoke" Adams wrote:
>> Is there a type of __THIS__ construct similar to __FILE__ and __LINE__?
>>
>> Something that returns the current this ptr if it exists, null otherwise.
>>
>> Log(string filename = __FILE__, Object obj = __THIS__)()
>> {
>> // inspect obj and do stuff
>> }
>
> There is no 'this' pointer unless you are calling a member function on an aggregate, so you can never have one that is null.
Oh, perhaps I misunderstood your question. Do you meant this:
class Foo() {
void bar() { Log(); } // Pass reference to Foo instance
}
void doSomething() { Log(); } // Null reference
If so, the answer is no. And I don't see how that could work as a compile time parameter, given that the reference itself is a runtime value.
|
June 24, 2016 Re: Get calling this, if exists | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On Friday, 24 June 2016 at 03:10:51 UTC, Mike Parker wrote:
> Oh, perhaps I misunderstood your question. Do you meant this:
>
> class Foo() {
> void bar() { Log(); } // Pass reference to Foo instance
> }
>
> void doSomething() { Log(); } // Null reference
>
> If so, the answer is no. And I don't see how that could work as a compile time parameter, given that the reference itself is a runtime value.
It actually is possible. You just have to be explicit.
void log(alias self)(string s)
{
pragma(msg, self.stringof);
}
struct Test
{
void test(string s)
{
log!this(s);
}
}
void main()
{
Test t;
t.test("asdf");
}
|
June 24, 2016 Re: Get calling this, if exists | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Friday, 24 June 2016 at 03:16:58 UTC, Meta wrote:
> On Friday, 24 June 2016 at 03:10:51 UTC, Mike Parker wrote:
>> Oh, perhaps I misunderstood your question. Do you meant this:
>>
>> class Foo() {
>> void bar() { Log(); } // Pass reference to Foo instance
>> }
>>
>> void doSomething() { Log(); } // Null reference
>>
>> If so, the answer is no. And I don't see how that could work as a compile time parameter, given that the reference itself is a runtime value.
>
> It actually is possible. You just have to be explicit.
>
> void log(alias self)(string s)
> {
> pragma(msg, self.stringof);
> }
>
> struct Test
> {
> void test(string s)
> {
> log!this(s);
> }
> }
>
> void main()
> {
> Test t;
> t.test("asdf");
> }
I don't want to be explicit! One can be explicit with __FILE__ too but one doesn't have to be.
I don't care if it's null.
|
June 24, 2016 Re: Get calling this, if exists | ||||
---|---|---|---|---|
| ||||
Posted in reply to "Smoke" Adams | On 6/24/16 11:15 AM, Smoke Adams wrote:
> On Friday, 24 June 2016 at 03:16:58 UTC, Meta wrote:
>> On Friday, 24 June 2016 at 03:10:51 UTC, Mike Parker wrote:
>>> Oh, perhaps I misunderstood your question. Do you meant this:
>>>
>>> class Foo() {
>>> void bar() { Log(); } // Pass reference to Foo instance
>>> }
>>>
>>> void doSomething() { Log(); } // Null reference
>>>
>>> If so, the answer is no. And I don't see how that could work as a
>>> compile time parameter, given that the reference itself is a runtime
>>> value.
>>
>> It actually is possible. You just have to be explicit.
>>
>> void log(alias self)(string s)
>> {
>> pragma(msg, self.stringof);
>> }
>>
>> struct Test
>> {
>> void test(string s)
>> {
>> log!this(s);
>> }
>> }
>>
>> void main()
>> {
>> Test t;
>> t.test("asdf");
>> }
>
> I don't want to be explicit! One can be explicit with __FILE__ too but
> one doesn't have to be.
__FILE__ is a constant, so is __LINE__. __THIS__ would not be, so this is somewhat different.
With UFCS, you can get close:
void log(T)(T obj, string s)
{
...
}
struct Test
{
void test(string s)
{
this.log(s);
}
}
But I believe you have to call with explict 'this'.
Perhaps an opDispatch can help, but seems an awful lot to avoid explicit passing of this variable.
-Steve
|
June 24, 2016 Re: Get calling this, if exists | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Friday, 24 June 2016 at 15:35:57 UTC, Steven Schveighoffer wrote:
> On 6/24/16 11:15 AM, Smoke Adams wrote:
>> On Friday, 24 June 2016 at 03:16:58 UTC, Meta wrote:
>>> On Friday, 24 June 2016 at 03:10:51 UTC, Mike Parker wrote:
>>>> Oh, perhaps I misunderstood your question. Do you meant this:
>>>>
>>>> class Foo() {
>>>> void bar() { Log(); } // Pass reference to Foo instance
>>>> }
>>>>
>>>> void doSomething() { Log(); } // Null reference
>>>>
>>>> If so, the answer is no. And I don't see how that could work as a
>>>> compile time parameter, given that the reference itself is a runtime
>>>> value.
>>>
>>> It actually is possible. You just have to be explicit.
>>>
>>> void log(alias self)(string s)
>>> {
>>> pragma(msg, self.stringof);
>>> }
>>>
>>> struct Test
>>> {
>>> void test(string s)
>>> {
>>> log!this(s);
>>> }
>>> }
>>>
>>> void main()
>>> {
>>> Test t;
>>> t.test("asdf");
>>> }
>>
>> I don't want to be explicit! One can be explicit with __FILE__ too but
>> one doesn't have to be.
>
> __FILE__ is a constant, so is __LINE__. __THIS__ would not be, so this is somewhat different.
>
> With UFCS, you can get close:
>
> void log(T)(T obj, string s)
> {
> ...
> }
>
> struct Test
> {
> void test(string s)
> {
> this.log(s);
> }
> }
>
> But I believe you have to call with explict 'this'.
>
> Perhaps an opDispatch can help, but seems an awful lot to avoid explicit passing of this variable.
>
> -Steve
The problem with UFCS is that I am using variadic parameters. The logging function isn't designed to accept the first parameter as this.
It would be much easier to simply have the compiler "insert" it using __THIS__. Just because it isn't constant isn't really that big of a deal to the compiler. It could just manually add the parameter at the end of of the arguments.
I would also have to convert all the calls to this.log.
This becomes problematic because not not all calls are inside objects.
We have __FUNCTION__ so, __THIS__ seems somewhat natural. Null for outside of objects is fine.
|
June 24, 2016 Re: Get calling this, if exists | ||||
---|---|---|---|---|
| ||||
Posted in reply to "Smoke" Adams | On 6/24/16 1:19 PM, Smoke Adams wrote: > > The problem with UFCS is that I am using variadic parameters. The > logging function isn't designed to accept the first parameter as this. Then you would need to change it? > It would be much easier to simply have the compiler "insert" it using > __THIS__. Just because it isn't constant isn't really that big of a deal > to the compiler. It could just manually add the parameter at the end of > of the arguments. Yes, easier for you not having to do anything. It's only the compiler writers who have to figure out how to add this feature for you :) > I would also have to convert all the calls to this.log. > > This becomes problematic because not not all calls are inside objects. Possibly you can use overloads. In any case, I think there is some work you need to do to get what you want. > We have __FUNCTION__ so, __THIS__ seems somewhat natural. Null for > outside of objects is fine. __FUNCTION__ is still a compile-time constant. Have you considered a mixin or opDispatch to help you out? (untested) mixin template addLog() { log(this This, T...)(T args) { return .log(cast(This)this, args); } } class MyBaseObj { mixin addLog; } class MyObj : MyBaseObj { void foo() { log(1, 2, 3); // calls .log(cast(MyObj)this, 1, 2, 3) } } -Steve |
June 24, 2016 Re: Get calling this, if exists | ||||
---|---|---|---|---|
| ||||
Posted in reply to "Smoke" Adams | On 06/24/2016 10:19 AM, Smoke Adams wrote: > We have __FUNCTION__ so, __THIS__ seems somewhat natural. Null for > outside of objects is fine. Would the following work, where you check the first argument? import std.stdio; void Log(string filename = __FILE__, T...)(T args) { static if (is (T[0] == typeof(null))) { writefln("working without an object for %s", args[1 .. $]); } else static if (is (T[0] == class)) { writefln("working with object %s and %s", args[0], args[1 .. $]); } else { // Recurse import std.meta : AliasSeq; return Log!filename(AliasSeq!(null, args)); } } class C { } void main() { Log(42, "hello"); auto c = new C(); Log(c, "cool"); c.Log("breeze"); } The output: working without an object for 42 working with object deneme.C and cool working with object deneme.C and breeze Ali |
Copyright © 1999-2021 by the D Language Foundation