3

Let's say that I have a function f which should return an attached T by calling g. However, g returns a detachable T. If g results in a Void, I want to raise an exception like this:

f: T
  do
    if attached g as res then
      Result := res
    else
      raise
    end
  end
  
raise
  do
    (create {DEVELOPER_EXCEPTION}).raise
  end

In this setup EiffelStudio gives me an error VEVI: Variable is not properly set. Variable: Result at the end of f.

Indeed, Result can be Void at the end of f but the execution should not reach the end of f in this case, an exception should have been raised.

How can I restructure the code to achieve a similar result?

Ilgiz Mustafin
  • 414
  • 1
  • 4
  • 15

3 Answers3

3

If the type of a raised exception does not matter, the following code will do:

f: T
    do
        Result := g
        check is_g_attached: attached Result then end
    end

If the type of the raised exception is important, the feature raise can be augmented with the postcondition False that indicates that the feature never returns. Then, the code would look like

f: T
    do
        Result := g
        if not attached Result then
            raise
        end
    end

raise
    do
        (create {DEVELOPER_EXCEPTION}).raise
    ensure
        False
    end
Alexander Kogtenkov
  • 5,770
  • 1
  • 27
  • 35
2

Just found out that checks can be used in this case:

f: T
  do
    if attached g as res then
      Result := res
    else
      raise
    end
    check attached Result then end
  end

However, I wonder if there is a cleaner way.

Ilgiz Mustafin
  • 414
  • 1
  • 4
  • 15
0

I think you can get away with:

f:T
   do
      check has_g: attached g then Result := g end
   end

The code will naturally break if the check-condition attached g is not True. Note that I use this construct quite a bit when I want to ensure that a feature like g is attached.

I will also code it as:

f:T
   do
      check has_g: attached g as al_result then Result := al_result end
   end

So, you might ask: How is this different and what is the "al_" prefix about?

  1. The first example doesn't have the as ____ clutter, which makes it easier to read and comprehend (IMHO).
  2. The "al_" prefix is a naming convention I follow, where "al" means "attachment local". As a reader of my code, I can then look at the variable name and know where the variable was declared.
  • If the variable has no prefix, then it is a feature reference on the class itself.

  • If the prefix is "l_?", then I look to the feature local declarations.

  • If "al_", then I look to a check or if .. then or other block for an as keyword.

  • I also use this for across loops, where ic_? is an "Iteration Cursor" local object. I use this naming convention applied to symbolic loops as well.

Liberty Lover
  • 844
  • 10
  • 12