Thread overview
what is special about unittest constants
Feb 08, 2013
Dan
Feb 08, 2013
anonymous
Feb 18, 2013
Lubos Pintes
Feb 18, 2013
Ali Çehreli
Feb 18, 2013
Lubos Pintes
Feb 18, 2013
Ali Çehreli
February 08, 2013
This constant in a module causes a compilation error of the "non-constant expression" variety.

DEFINITION 1
  const(AssetProjectionMap) SavingsGrowth2013 = [
    AssetReturnType.Interest :
    RateCurve([DateRate(Date.min, CcRate(0.007))]),
  ];

The fix that addresses this error at module level is:

DEFINITION 2

const(AssetProjectionMap) SavingsGrowth2013;
static this() {
  SavingsGrowth2013 = [
    AssetReturnType.Interest :
    RateCurve([DateRate(Date.min, CcRate(0.007))]),
  ];
}


However, the same constant, when defined in a unittest block works with DEFINITION 1. What is the reason for the difference between unittest constants and module constants?

Thanks,
Dan
February 08, 2013
On Friday, 8 February 2013 at 20:12:41 UTC, Dan wrote:
> This constant in a module causes a compilation error of the "non-constant expression" variety.
>
> DEFINITION 1
>   const(AssetProjectionMap) SavingsGrowth2013 = [
>     AssetReturnType.Interest :
>     RateCurve([DateRate(Date.min, CcRate(0.007))]),
>   ];
>
> The fix that addresses this error at module level is:
>
> DEFINITION 2
>
> const(AssetProjectionMap) SavingsGrowth2013;
> static this() {
>   SavingsGrowth2013 = [
>     AssetReturnType.Interest :
>     RateCurve([DateRate(Date.min, CcRate(0.007))]),
>   ];
> }
>
>
> However, the same constant, when defined in a unittest block works with DEFINITION 1. What is the reason for the difference between unittest constants and module constants?
>
> Thanks,
> Dan

unittest blocks are evaluated at run time, just like your DEFINITION 2, and unlike your DEFINITION 1 which would be evaluated at compile time.
February 18, 2013
Yesterday I solved similar problem by using enum.
enum GameInfo[string] games=[
...
];
Dňa 8. 2. 2013 21:21 anonymous  wrote / napísal(a):
> On Friday, 8 February 2013 at 20:12:41 UTC, Dan wrote:
>> This constant in a module causes a compilation error of the
>> "non-constant expression" variety.
>>
>> DEFINITION 1
>>   const(AssetProjectionMap) SavingsGrowth2013 = [
>>     AssetReturnType.Interest :
>>     RateCurve([DateRate(Date.min, CcRate(0.007))]),
>>   ];
>>
>> The fix that addresses this error at module level is:
>>
>> DEFINITION 2
>>
>> const(AssetProjectionMap) SavingsGrowth2013;
>> static this() {
>>   SavingsGrowth2013 = [
>>     AssetReturnType.Interest :
>>     RateCurve([DateRate(Date.min, CcRate(0.007))]),
>>   ];
>> }
>>
>>
>> However, the same constant, when defined in a unittest block works
>> with DEFINITION 1. What is the reason for the difference between
>> unittest constants and module constants?
>>
>> Thanks,
>> Dan
>
> unittest blocks are evaluated at run time, just like your DEFINITION 2,
> and unlike your DEFINITION 1 which would be evaluated at compile time.

February 18, 2013
On 02/18/2013 08:59 AM, Lubos Pintes wrote:
> Yesterday I solved similar problem by using enum.
> enum GameInfo[string] games=[
> ...
> ];

Be careful with that though: 'games' is a literal associative array, meaning that it will be used in the program as if it's copy-pasted in that location. It looks like there is a single associative array, but there is a new temporary created every time you use 'games':

struct GameInfo
{
    int i;
}

enum GameInfo[string] games = [ "one" : GameInfo(1) ];

void main()
{
    assert(&(games["one"]) != &(games["one"]));    // note: !=
}

As the two games are different, their elements are not at the same location.

This is one way to go:

struct GameInfo
{
    int i;
}

static immutable GameInfo[string] games;

static this()
{
    games = [ "one" : GameInfo(1) ];
}

void main()
{
    assert(&(games["one"]) == &(games["one"]));    // note ==
}

This time there is just one 'games'.

Ali

February 18, 2013
Thank for explanation. I supposed that the enum constant is fixed and that it is also true for AA.
I will convert my code before I forget. :-).
Dňa 18. 2. 2013 18:22 Ali Çehreli  wrote / napísal(a):
> On 02/18/2013 08:59 AM, Lubos Pintes wrote:
>  > Yesterday I solved similar problem by using enum.
>  > enum GameInfo[string] games=[
>  > ...
>  > ];
>
> Be careful with that though: 'games' is a literal associative array,
> meaning that it will be used in the program as if it's copy-pasted in
> that location. It looks like there is a single associative array, but
> there is a new temporary created every time you use 'games':
>
> struct GameInfo
> {
>      int i;
> }
>
> enum GameInfo[string] games = [ "one" : GameInfo(1) ];
>
> void main()
> {
>      assert(&(games["one"]) != &(games["one"]));    // note: !=
> }
>
> As the two games are different, their elements are not at the same
> location.
>
> This is one way to go:
>
> struct GameInfo
> {
>      int i;
> }
>
> static immutable GameInfo[string] games;
>
> static this()
> {
>      games = [ "one" : GameInfo(1) ];
> }
>
> void main()
> {
>      assert(&(games["one"]) == &(games["one"]));    // note ==
> }
>
> This time there is just one 'games'.
>
> Ali
>

February 18, 2013
On 02/18/2013 09:22 AM, Ali Çehreli wrote:

> static immutable GameInfo[string] games;
>
> static this()
> {
> games = [ "one" : GameInfo(1) ];
> }

And to be honest, I am not sure why I define it as 'static immutable'. :) Isn't this the same thing?

immutable GameInfo[string] games;

static this()
{
    games = [ "one" : GameInfo(1) ];
}

Ali