rubyoverridingrefinements

Difference between Refinements and redefine class in ruby


I'm reading some book for ruby programming language and was wondering how something like this works

class String
  def word_count
    frequencies = Hash.new(0)
    downcase.scan(/\w+/) { |word| frequencies[word] += 1 }
    return frequencies
  end
end

I know there is a build-in string, I came from (C++) btw, So creating class string will make ambiguity when defining an object string x = new string(), I search about that and i found some concept is named refinement which is allowing us to modify and add functions to String class, I see them using keyword refine to make these things(according to the docs), but here my questions come, When i just put the above class on the irb and started to test it like that "amr adel".word_count, It gave me the correct result, I expected not to work at first, So if it works why could i even use refine in my code why don't i only create a class with same name of the built-in one and put additional function and modify functions, Are this way doing the refinement process implicitly?

I admit that ruby is amazing and so easy to work with, but i want to know things goes on.

If you could refer some articles or something it will be extremely appreciated Thanks


Solution

  • From the ruby documentation:

    You may activate refinements at top-level, and inside classes and modules. You may not activate refinements in method scope. Refinements are activated until the end of the current class or module definition, or until the end of the current file if used at the top-level.

    The whole point of refinements (as opposed to just extending a core class) is that they are scoped.

    In your code above, String#word_count will be defined everywhere - for example, if you have multiple files.

    On the other hand, if you define that method as a refinement then it will only be defined in places where you are explicitly using it.

    The motivation for this is that you can add/alter behaviour in one location without it impacting code elsewhere.