Class Contracts: ensure not working with Property gettor?

The following code, does NOT pass compiler - what am I missing?

property MyFunkyName: String 
  read begin
    result := GetMyFunkyName;
  ensure
    result.Contains('  ');
  end;

Define “not pass compiler”?

@mh marc - sorry I should have been more clear.

The compiler indicated that the code is wrong, as seen in the figure below.

A sample project is attached for reproducing the issue (honestly, I am not sure if it is an issue, or it is just that I didn’t use the “ensure” feature correctly).

ConsoleApplication.7z (2.7 KB)

That is a block. I don’t think a. block can have an ensure and require part.
The idea is nice but I think not so easy to manage

I think you are correct.
This will work:

property MyFunkyName: String read GetMyFunckyName;
  private method GetMyFunckyName: String begin
    result := GetMyFunkyName;
  ensure
    result.Contains('  ');
  end;

@Theo69
In the solution you outlined, would the private method GetMyFunckyName be only accessible (i.e., local) to property MyFunkyName? Or it can be used by other class members internally as well?

it is a normal private method.

Got it. Also thank you for pointing out the “block” nature of that gettor. I think I still would like it to be a block which is "local" to the property it applies.

You can do it in a block too, but not with ensure:

property MyFunkyName: String read begin
    result := GetMyFunkyName;
  {$Ifdef debug}
    assert(result.Contains('  '),"Result does not contain '  '");
  {$endif}
  end;
1 Like

@Theo69 - Yes, I used the “conventional” assert.

Why not simply the ensure in the GetMyFunkyName; ?
Not sure but I think a property block has also a runtime overhead.

If this is not what you want because of using the GetMyFunkyName at other places
the resolution from Theo69 but as inline?
like:

 private method GetMyFunckyName: String; inline; 
begin
    result := GetMyFunkyName;
  ensure
    result.Contains('  ');
end;
1 Like

To prevent it to be used from other places:

[EditorBrowsable(never)]
private method Get_MyFunckyName: String; inline; 
begin
    result := GetMyFunkyName;
  ensure
    result.Contains('  ');
end;
1 Like

@FritzW

The reason (good, or bad) is - GetMyFunkyName is declared as a pure abstract method, to be overridden by a subclass. And I want the parent class to take care of the “post-condition check”.

@ck, do we wanna support require/ensure in property getter/setters as shown in the OP?

3 Likes

Out of Interest , are this Kind of setter/ geter compiler inline without runtime costs?

They’ll generate the same code as using a getter/setter method, as that’s what required on the runtime level, anyways. You could mark a property inline, but then any underlying field(s) to accesses would have to be public, as well…

1 Like

Do note that on .net and java, the runtime will inline any property access when running optimized (compiled for release, no debugger). On Island the optimizer will do the same kind of thing.

Thanks, logged as bugs://82950