Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overwriting attr_* methods in Ruby

Tags:

ruby

I'm reading this book "The Well-Grounded Rubyist" and this random question came to me. I know in Ruby that it's possible to re-open a class and overwrite the method.

Example:

class A
  def x
    "First definition of x"
  end

  def x
    "Second definition of x"
  end
end

test = A.new
test.x #returns "Second definition of x"

Based on the results above, I was curious if it was possible to overwrite the class method attr_accessor with my own (random) definition. Here's what I'm thinking:

class Dummy
  attr_accessor :test

  def self.attr_accessor(method_name)
    puts "Overwrite the default functionality of attr_accessor by printing this text instead."
  end
end

d = Dummy.new
d.test #not sure why this returns nil instead of putting my message
Dummy.attr_accessor(test) #fails because of ArgumentError: wrong number of arguments (0 for 2..3)

For the two examples above, I'm hoping to understand Ruby better by tinkering around and asking questions to get your insight.

like image 668
wmock Avatar asked Jun 22 '26 16:06

wmock


1 Answers

You are on the right path, but class definitions are executed in order at runtime. You need to define your new method before calling it, otherwise the original gets used for that one.

If you do

class Dummy
  def self.attr_accessor(method)
    puts 'your message here'
  end
  attr_accessor :test # message printed
end

d = Dummy.new
d.test # raises an error, since we aren't creating a test method anymore
Dummy.attr_accessor(test) #will still fail, read on

test is a method in Ruby, corresponding to the test builtin in shells. That method is why you are getting an error at the end. What you are actually wanting is

Dummy.attr_accessor(:test1)

Note that you won't be able to call the normal attr_accessor, because it is a private method on the class instance that is self inside of the class definition. (IOW, attr_accessor is a private, instance method on Module, and when executing the class definition, self is an instance of Module)

like image 96
Jim Deville Avatar answered Jun 25 '26 18:06

Jim Deville



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!