firetonton
firetonton

Reputation: 323

Ruby: Dynamically create classes with value

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 ?

Upvotes: 1

Views: 45

Answers (1)

tadman
tadman

Reputation: 211540

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".

Upvotes: 4

Related Questions