1

I search for a clean way to define Exception dependencies in a ruby app. Here is something I would like to approach (the following example doesn't work):

def error_class(superclass, http_code_value)
  Class.new(superclass) do
    def http_code
      http_code_value
    end
  end
end

class AppError < StandardError
  def to_s
    "Here is my code: #{http_code}"
  end

  # other methods ...
end

# Clean error tree build
ClientError = error_class AppError, 400
ServerError = error_class AppError, 500
TeapotError = error_class ClientError, 418
# and so on ...

puts "client #{ClientError.new}" # client Here is my code: 400
puts "server #{ServerError.new}" # server Here is my code: 500
puts "teapot #{TeapotError.new}" # teapot Here is my code: 418

The problem here is the parameter _http_code is evaluated in the class context: it doesn't exist.

Is there a way I can achieve it without relying on eval ?

2
  • usually preceding an argument with an underscore specifies that this argument is not used. Commented Nov 2, 2017 at 20:56
  • I agree, in this case I added the underscore to not conflict with the http_code name to be 100% sure there is no infinite recursion. But I should have renamed it with an other name. Commented Nov 2, 2017 at 21:11

1 Answer 1

4

It's a pretty minor reworking to get the right context:

def error_class(_superclass, _http_code)
  Class.new(_superclass) do
    define_method(:http_code) do
      _http_code
    end
  end
end

When using define_method it creates them in the correct context by default. As a note there's really nothing special about these variables, so the _ prefix should be ditched. As engineersmnky points out, _ usually indicates "unused", "not important" or "unavoidable temporary copy for which I apologize profusely".

Sign up to request clarification or add additional context in comments.

1 Comment

Oh... I was 100% sure I tried define_method .. Thank you for this quick and efficient answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.