3

I've come across some code in a Rails app in the form of

ThirdPartyLibrary::Foo.class_eval do
  def bar?
    @bar_field == 'true'
  end
end

and I'm wondering why they didn't just do

class ThirdPartyLibrary::Foo
  def bar?
    @bar_field == 'true'
  end
end

Are there any advantages in using class_eval when there isn't anything you want to pass in to the new code?

Prashanth Chandra
  • 2,672
  • 3
  • 24
  • 42
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
  • Is the rails app you mentioned open source? If so, can you post the link? – tompave May 03 '15 at 01:40
  • Also, what's the library being monkey-patched? What's the patch? – tompave May 03 '15 at 01:40
  • @tompave sorry, it isn't open source. – Andrew Grimm May 03 '15 at 01:46
  • 4
    I don't know the answer for sure, but one thing is that with class_eval, you are sure that the class will already be loaded before the code is evaluated. If you just open the class definition, even if the class is not yet loaded, it will be created. In the second case, if the same methods are then defined, your code will be overwritten. –  May 03 '15 at 05:55
  • @AndrewGrimm ok, no problem. What about the third party library? And the code being added? – tompave May 03 '15 at 08:58

1 Answers1

0
class ThirdPartyLibrary::Foo do
  def original?
    true
  end
end

ThirdPartyLibrary::Foo.class_eval do
  def baz?
    true
  end
end

ThirdPartyLibrary::Foo.original? #=> true
ThirdPartyLibrary::Foo.baz? #=> true

class ThirdPartyLibrary::Foo
  def bar?
    true
  end
end

ThirdPartyLibrary::Foo.original? #=> undefined method
ThirdPartyLibrary::Foo.baz? #=> undefined method
ThirdPartyLibrary::Foo.bar? #=> true

class_eval 'adds' something to an existing class and your second example just defines the class new and overwrites everything that was there before. This is used for example when you want to monkeypatch or extend libraries.

Denny Mueller
  • 3,505
  • 5
  • 36
  • 67