In Rails, how to add a new method to String class?
You can define a new class in your application at lib/ext/string.rb
and put this content in it:
class String
def to_magic
"magic"
end
end
To load this class, you will need to require it in your config/application.rb
file or in an initializer. If you had many of these extensions, an initializer is better! The way to load it is simple:
require 'ext/string'
The to_magic
method will then be available on instances of the String
class inside your application / console, i.e.:
>> "not magic".to_magic
=> "magic"
No plugins necessary.
Adding custom methods to standard ruby objects
Just open the class and add the method. You can open a class as many times as you need to.
class Fixnum
def lucky?
self == 7
end
end
95.lucky?
=> false
7.lucky?
=> true
It's a useful ability and we've all done it. Take care that your code is maintainable and that you don't break basic functionality.
Re-open String class and add .upcase method in Ruby
Extending core classes is fine to do so long as you're careful, especially when it comes to re-writing core methods.
Remember whenever you're inside an instance method then self
always refers to the instance:
def my_special_upcase
self.upcase + '!'
end
So self
refers to the string in question.
Add method to the String class in a Rails app
You should create a rb file with the same content and put it in config/initializers.
It will get loaded during initialization of your Rails application and these new methods will be available for all string objects.
In Ruby on Rails, to extend the String class, where should the code be put in?
I always add a core_ext
directory in my lib
dir.
Create an initializer for loading the custom extensions (for example: config/initializers/core_exts.rb
). And add the following line in it:
Dir[File.join(Rails.root, "lib", "core_ext", "*.rb")].each {|l| require l }
and have your extension like:
lib/core_ext/string.rb
class String
def capitalize_first
# ...
end
end
What is the proper way to add a method to a built-in class in ruby?
tenebrousedge there was probably hinting at refinements.
Or, rather, not patching String
at all. More often than not, monkeypatching creates more problems than it solves. What if String already knew alpha?
and it did something different?
For example, future versions of ruby might add String#alpha?
that will handle unicode properly
'新幹線'.alpha? # => true
and your code, as it is, would overwrite this built-in functionality with an inferior version. Now your app is breaking in all kinds of places, because stdlib/rails assumes the new behaviour. Chaos!
This is to say: avoid monkeypatching whenever possible. And when you can't avoid, use refinements.
How to create new functions for String class in Ruby?
You have defined functions on String
instance, hence:
def check(key)
puts case
when key.is_i?
"Could be a number"
when key.is_path?
"This is a path"
else
"Ok"
end
end
or
def check(key)
puts case key
when ->(s) { s.is_i? }
"Could be a number"
when ->(s) { s.is_path? }
"This is a path"
else
"Ok"
end
end
UPD Please also note that I removed superfluous subsequent calls to puts
.
add methods directly called on model
So I tested this myself && further to @max
's answer (which I kind of thought anyway, but he definitely pointed it out properly)...
There are a number of resources you can use:
- Paperclip's
has_attached_file
- FriendlyID's
friendly_id
- Ruby Metaprogramming: Declaratively Adding Methods to a Class
- Intend to extend
After some brief researching, I found this question:
Ruby on Rails - passing a returned value of a method to has_attached_file. Do I get Ruby syntax wrong?
The problem is that you're trying to use an instance method
picture_sizes_as_strings
in a declaration (has_attached_image
)
What you're looking for is something to do with declaring a class. I have as much experience as you with this, so I'm writing this for my own benefit:
For those coming from static object oriented languages, such as C++ and Java, the concept of open classes is quite foreign. What does it mean that Ruby has open classes? It means that at run time the definition of a class can be changed. All classes in Ruby are open to be changed by the user at all times.
class Talker
def self.say(*args)
puts "Inside self.say"
puts "self = #{self}"
args.each do |arg|
method_name = ("say_" + arg.to_s).to_sym
send :define_method, method_name do
puts arg
end
end
end
end
class MyTalker < Talker
say :hello
end
m = MyTalker.new
m.say_hello
It seems that if you delcare the class, it will run the declarative (?) methods at init. These methods can be used to populate other parts of the object... in the case of has_many :associations
, it would create an instance method of @parent.associations
.
Since ActiveRecord::Concerns
are modules, you need to treat them as such (according to the epic tutorial I found):
#app/models/concerns.rb
require 'active_support/concern'
module Helper
extend ActiveSupport::Concern
module ClassMethods
def help(*args) #-> each argument represents a method
args.each do |arg|
method_name = ("say_" + arg.to_s).to_sym
send :define_method, method_name do
puts arg
end
end
end
end
end
#app/models/x.rb
class X < ActiveRecord::Base
include Helper
help :help
end
@x = X.new
@x.say_help #-> puts "help"
[[still working out the rest]] -- how to add to instance methods; seems super
doesn't work so well
Add method to base class in the context of module
One option is to use ::
to ensure you are grabbing the top-level String class:
module A
class ::String
def my_own_method
self.reverse
end
end
end
"some string".my_own_method # => "gnirts emos"
I also have to agree with Sergio's point at the end of his answer. Not really sure of the need to do this.
Related Topics
Convert Time from One Time Zone to Another in Rails
Difference Between Ruby and Ruby on Rails
Rails 4.0 Strong Parameters Nested Attributes With a Key That Points to a Hash
How to Assign Hash['A']['B']= 'C' If Hash['A'] Doesn't Exist
How to Use CSS with a Ruby on Rails Application
Split the String to Get Only the First 5 Characters
Ruby:Difference Between Instance and Local Variables in Ruby
In Ruby, Why Does Nil[1]=1 Evaluate to Nil
What Is the Purpose of "!" and "" at the End of Method Names
Installing Nokogiri on Osx 10.10 Yosemite
Ruby 1.9.2 How to Install Rmagick on Windows
Rails Engines Extending Functionality
Read and Write Yaml Files Without Destroying Anchors and Aliases
How to Use Gem to Install Rails on Ubuntu