barsoom / attr_extras

Takes some boilerplate out of Ruby with methods like attr_initialize.
MIT License
560 stars 31 forks source link

Do we want to support BasicObject? #15

Closed joakimk closed 9 years ago

joakimk commented 9 years ago
require "attr_extras"

class Foo < BasicObject
  pattr_initialize :bar

  def hello
    bar
  end
end

Foo.new("bar-value").hello
undefined method `instance_variable_set' for #<Foo:0x007f7bace49a38> (NoMethodError)
henrik commented 9 years ago

Definitely worth exploring how easy it would be to support it. If this is the only issue we could probably work around it. If nothing else, we could make the error message better.

henrik commented 9 years ago

Hm, looked into this a bit. BasicObject doesn't have #class either, for example. And Object#class is defined in C, so it's perhaps not trivial to reimplement.

So I suspect it wouldn't be easy to make it work, and it would probably uglify the code quite a bit.

But a better error message is probably achievable.

henrik commented 9 years ago

We can definitely do the error message, but I'm not convinced we should.

Something like this seems to do it:

def pattr_initialize(*names, &block)
  raise "helpful error" if self < BasicObject && !(self < Object)
  # …
end

The first condition is necessary because we probably want to keep allowing attr_extras in mixin modules, not just classes.

But I'm not sure we'll add much value by adding such a guard everywhere. Doesn't seem like a ducktype-y way of going about things, either. Maybe we should just doc this constraint, and if someone really wants to use attr_extras in SimpleObject, they will need to reimplement a bunch of methods, or switch to regular Object.

I'll close this ticket and probably add such docs.

joakimk commented 9 years ago

I think documenting it is the way to go.