migu
migu

Reputation: 4336

Can't extend core Class

I'm trying to extend core classes and have no idea why the following fails when being called through the Rails 4 console:

# config/application.rb
config.autoload_paths += Dir["#{config.root}/lib/**/"]

# lib/core_ext/string.rb
class String
  def test
    self + " some test"
  end
end

# lib/core_ext/array.rb
class Array
  def mean
    sum / size if sum && size
  end
end

# lib/core_ext/test.rb
class Test
  def test
    "some test"
  end
end

Rails console output:

1] pry(main)> test = Test.new
#<Test:0x007ff63971b588>
[2] pry(main)> test.test
"some test"
[3] pry(main)> "string".test
NoMethodError: private method `test' called for "string":String
from (pry):3:in `__pry__'
[4] pry(main)> [1,2,3].mean
NoMethodError: undefined method `mean' for [1, 2, 3]:Array
from (pry):4:in `__pry__'

Upvotes: 3

Views: 2544

Answers (3)

konyak
konyak

Reputation: 11716

I would add the following:

# In config/initializers/require.rb:
require "core_ext/string" 
require "core_ext/array" 
require "core_ext/test"

And not modify config/application.rb's autoload_paths, which do not eager load your extensions. If a module or class is already loaded somewhere else, it won't extend it. For references, check these SO question1 and question2

Upvotes: 4

guyaloni
guyaloni

Reputation: 5872

Notice that if you are interested in static methods (e.g. String.test) you you declare it as def self.test.

Upvotes: 1

Karthik T
Karthik T

Reputation: 31952

You should add the following line to effectively require the files into your project

Dir[File.join(Rails.root, "lib", "core_ext", "*.rb")].each {|l| require l }

Taken from In Ruby on Rails, to extend the String class, where should the code be put in?

Upvotes: 4

Related Questions