www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why does not UFCS work for method defined inside unittest block?

reply Ky-Anh Huynh <saigon example.net> writes:
Hi,

Can I define a new quick function to use inside a unittest block?

I have the following code:

[code]
auto foo(string[] sta) {
   return sta;
}

auto bar(string[] sta) {
   return sta;
}

auto h(string[] sta) {
   return sta.foo.bar;
}

unittest {
   import std.format;

   auto f = (string[] sta) => sta.foo.bar;
   auto g(string[] sta) {
     return sta.foo.bar;
   }

   assert(f(["test"]) == ["test"]);
   assert(g(["test"]) == ["test"]);
   assert(["test"].h == ["test"]);
   assert(["test"].g == ["test"]);
}
[/code]

(Src: 
https://gist.github.com/icy/64ec1838929d448d9f874d1e8261e56a)

The last test will fail: Error: no property g for type string[]

Please advise.

Thanks a lot.
Jul 31 2018
next sibling parent Ky-Anh Huynh <saigon example.net> writes:
dmd version that I'm using:

$ dmd --version
DMD64 D Compiler v2.081.1-dirty
Copyright (C) 1999-2018 by The D Language Foundation, All Rights 
Reserved written by Walter Bright
Jul 31 2018
prev sibling parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Tuesday, 31 July 2018 at 08:28:01 UTC, Ky-Anh Huynh wrote:
 Hi,

 Can I define a new quick function to use inside a unittest 
 block?

 I have the following code:

 [code]
 auto foo(string[] sta) {
   return sta;
 }

 auto bar(string[] sta) {
   return sta;
 }

 auto h(string[] sta) {
   return sta.foo.bar;
 }

 unittest {
   import std.format;

   auto f = (string[] sta) => sta.foo.bar;
   auto g(string[] sta) {
     return sta.foo.bar;
   }

   assert(f(["test"]) == ["test"]);
   assert(g(["test"]) == ["test"]);
   assert(["test"].h == ["test"]);
   assert(["test"].g == ["test"]);
 }
 [/code]

 (Src: 
 https://gist.github.com/icy/64ec1838929d448d9f874d1e8261e56a)

 The last test will fail: Error: no property g for type string[]

 Please advise.
From https://dlang.org/spec/function.html#pseudo-member: "A free function can be called with a syntax that looks as if the function were a member function of its first parameter type." A function defined in a function scope (which a unittest block is), is not a free function, and so does not benefit from UFCS. There is an explanation for why at the bottom of the above page: "The reason why local symbols are not considered by UFCS, is to avoid unexpected name conflicts." If you need a function that's available for UFCS in a unittest but is not there in a non-unittest context, use a version block: version (unittest) { auto fun(string[] s) { return s } } And if you need something with a context: version (unittest) { string delegate (string) test; } unittest { string s1 = "foo"; test = s => s ~ s1; "foo".test; } -- Simen
Jul 31 2018
parent Ky-Anh Huynh <saigon example.net> writes:
On Tuesday, 31 July 2018 at 08:42:28 UTC, Simen Kjærås wrote:
 

 From https://dlang.org/spec/function.html#pseudo-member:
 "A free function can be called with a syntax that looks as if 
 the function were a member function of its first parameter 
 type."

  [...]
Thanks a lot Simen :)
Aug 01 2018