5

I'm playing around with Pharo, and would like to raise a customized error/exception/something, but I've got no idea how.
I've browsed the relevant (I think) chapters of "Pharo by Example" and "Deep into Pharo"; but couldn't make heads or tails about it - it seems way above the level that I need...

I've got a setter for a variable, and would like to raise an error/exception if the input isn't an Integer:


    MyClass >> someVariable: anInteger
       anInteger isInteger
          ifFalse: [ self SomehowProtestLoadly - the part I don't know how to do ].
       someVariable := anInteger

Just aborting or exiting would be sufficient... but if possible, I'd like to do it with a bit more "flare" - and in a more explainatory way...

lurker
  • 56,987
  • 9
  • 69
  • 103
Baard Kopperud
  • 577
  • 1
  • 5
  • 12

1 Answers1

6

The easiest way is to just signal a generic error:

someVariable: anInteger
  anInteger isInteger
    ifFalse: [self error: 'must be an Integer'].
  someVariable := anInteger

Now, if you want to signal a specific error, do the following:

  1. Create a subclass of Error, say, NonIntegerArgument
  2. Write your code like this

    someVariable: anInteger
      anInteger isInteger
        ifFalse: [NonIntegerArgument signal: 'must be an Integer'].
      someVariable := anInteger
    
  3. For handling this exception do the following

    [myObject someVariable: self value]
      on: NonIntegerArgument
      do: [:ex | self handleException: ex]
    

Note that your exception could provide more information, say the actual argument that was sent. To do this add an instance variable to your NonIntegerArgument class, namely, argument. Add a getter and a setter for it. Then

NonIntegerArgument class >> #signal: aString argument: anObject
  ^self new
    argument: anObject;
    signal: aString

and use it this way

someVariable: anInteger
  anInteger isInteger
    ifFalse: [
      NonIntegerArgument
        signal: 'must be an Integer'
        argument: anInteger].
  someVariable := anInteger

Now, the ex variable will be able to respond with the argument of the offending message.

Leandro Caniglia
  • 14,495
  • 4
  • 29
  • 51
  • 1
    Note that the string `'must be an Integer'` is generic enough to be encoded as a default message in `NonIntegerArgument` class rather than repeated at each client. The option for passing a client specific String can eventually be usefull or not, up to OP to decide. – aka.nice Oct 30 '17 at 17:32
  • 1
    @aka.nice Good point. Indeed, once you have a specific class for your exception, you can add a lot more of default behavior moving code from the client to the exception object. – Leandro Caniglia Oct 30 '17 at 17:37