In Rails, How to Add a New Method to String Class

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



Leave a reply



Submit