Ruby: overriding the puts method
def puts(o)
if o.is_a? Array
super(o.to_s)
else
super(o)
end
end
puts [1,2,3] # => [1, 2, 3]
or just use p
:
p [1, 2, 3] # => [1, 2, 3]
Is there a way to redefine a method within a block?
On second thoughts, here's a better answer:
def always_upcase_strings(&block)
anon_class = Class.new do
def puts(str)
super(str.upcase)
end
end
anon_class.new.instance_eval(&block)
end
always_upcase_strings do
puts "abc" #=> "ABC"
puts "def" #=> "DEF"
puts "ghi" #=> "GHI"
end
puts "xyz" #=> "xyz"
This creates a temporary class (anonymous, because it has no need for a name) with the desired method override.
The yielded block is then invoked, within the context of this class instance.
As well as being less confusing than my "redefine-undefine-redefine the method" solution, this approach has the added advantage that it's thread-safe. So you won't get weird behaviour if, for example, running parallel tests whilst invoking the method.
...But I still stand by my original statement that redefining methods within a block is super surprising behaviour. Coworkers probably won't like you for choosing that design pattern (unless it's done in a limited manner, and for good reason!)
How to override Ruby + method?
It seems you use ruby < 2.4. If so you want to patch Fixnum
and not Integer
. Be careful as the system itself uses numbers as well.
class Fixnum
alias_method :add, :+
def +(other)
puts 'plus method overridden'
add(other)
end
end
puts 5 + 9
how to monkey patch the puts method in ruby
You could override the puts
method like so:
def puts(object)
super('')
super(object)
super('')
end
If you really wanted to you could monkey patch the method like below. Although your changes would probably have unintended effects.
module Kernel
def puts(object)
# code
end
end
You can read about monkey patching in the Ruby docs here.
Overriding to_s method in ruby
def to_s
"I am a hi man"
end
You need to return the value, not output it.
Add functionality to a method by overriding, but still call original method
alias :old_fake_method :fake_method
def fake_method(cmd)
if (cmd) == "bla"
puts "caught cmd"
else
old_fake_method(cmd)
end
end
Is it possible to override a built-in Ruby method outside of a class or module?
The easiest way would be to split the string in a number and word, and sort by an Array of minus number (to get decreasing numbers) and word :
arr = ['2 xxx', '20 axxx', '2 m', '38 xxxx', '20 bx', '8540 xxxxxx', '2 z']
arr.sort_by! do |number_word|
number, word = number_word.split
[ -number.to_i, word ]
end
puts arr
# =>
# 8540 xxxxxx
# 38 xxxx
# 20 axxx
# 20 bx
# 2 m
# 2 xxx
# 2 z
When sorting arrays, the first element (-number
) has priority. If both first elements are the same, the sort uses the second element (word
).
ruby - override method and then revert
Another way to do that, without creating an extra method, is this:
class Foo
def bar
:old_method
end
end
Foo.new.bar # => :old_method
$old_method = Foo.new.method(:bar)
class Foo
def bar
:new_method
end
end
Foo.new.bar # => :new_method
class Foo
define_method($old_method.name, &$old_method)
end
Foo.new.bar # => :old_method
I think that this is better than using an alias method. In Ruby methods are, also, objects. I just take the reference of the object before destructing the association of the object (the method) with the class. After I add the same method. It also works if you use the undef
keyword to remove the method from the class. The bad point is that you have to have an object of the class to take the reference of the method.
Overriding a method with a getter in Ruby
attr_reader :action_label
is just defining a method. "getters" in Ruby are just methods like this
def action_label
@action_label
end
attr_reader
is shorthand for defining such a method.
There is nothing wrong with redefining a method in a subclass, that's one of the big features of OOP.
Also that is not what NotImplementedError is for. Raise something else.
Related Topics
Controller Method #Show Getting Called
Ruby: How Does Constant-Lookup Work in Instance_Eval/Class_Eval
Check If Folder Exist in S3 Bucket
Compare the Content, Not the Results, of Procs
Is It Acceptable Having Parameter in Class Constructor
What Do Ruby's Printf Arguments Mean
Get Instance Variable Name from Itself in Ruby
Rails User Profile Page Only Accessible to Correct User
Ruby/Rails - How to Validate Against Decimal Scale
Can a Watir Browser Object Be Re-Used in a Later Ruby Process
Is It a Good Idea to Pass a Huge String as an Argument to Sidekiq Worker
Have Delayed_Job Log "Puts", SQL Queries and Jobs Status
Actioncable Connected Users List
Setting a Global Within a Proc
How to Programmatically Convert Mp3 to an Itunes-Playable Aac/M4A File
How to Change Environment Variables When Running Rspec for Ruby