Removing Methods (MOTM 2010.01)

Preview:

Citation preview

Removing MethodsRuby Method of the MonthKevin Munc => @muncman

Adding a Method

class String def ruby_rocks? true #dat endend

Fancy New Method

"rails".ruby_rocks?=> true

Remove It!class String remove_method :ruby_rocks?end

Remove It!class String remove_method :ruby_rocks?end"rails".ruby_rocks?NoMethodError: undefined method `ruby_rocks?' for "rails":String

A Redefined Method

class Crb def to_s "Thanks Randall!" endend

Redefinition in Action

columbusrb = Crb.new

Redefinition in Action

columbusrb = Crb.new

columbusrb.to_s

Redefinition in Action

columbusrb = Crb.new

columbusrb.to_s=> "Thanks Randall!"

Redefinition Removalclass Crb remove_method :to_send

Note that we didn’t have to get a new instance for the removal to take effect.

Redefinition Removalclass Crb remove_method :to_send

Note that we didn’t have to get a new instance for the removal to take effect.

columbusrb.to_s

Redefinition Removalclass Crb remove_method :to_send

Note that we didn’t have to get a new instance for the removal to take effect.

columbusrb.to_s=> "#<Crb:0x101651538>"

Inherited Methodror = “Ruby on Rails”ror.to_s=> "Ruby on Rails"

We get the to_s from Object.

Note that the removal takes effect for instances already declared.

Inherited Methodror = “Ruby on Rails”ror.to_s=> "Ruby on Rails"

We get the to_s from Object.

Note that the removal takes effect for instances already declared.

class String remove_method :to_send

Inherited Methodror = “Ruby on Rails”ror.to_s=> "Ruby on Rails"

We get the to_s from Object.

Note that the removal takes effect for instances already declared.

class String remove_method :to_sendror.to_s=> "#<String:0x101682b88>"

Removal Locationclass Object remove_method :to_send

Defined in Kernel.

Object mixes in Kernel.

Removal Locationclass Object remove_method :to_send

Defined in Kernel.

Object mixes in Kernel.

NameError: method `to_s' not defined in Object

Put It All Back

class Crb def to_s "Thanks Randall!" endend

Starting from a clean slate, so String still has to_s, etc.

Undefine the Redefine Different than removal!

class Crb undef_method :to_send

Interesting that the default output of to_s is present in the output.

Undefine the Redefine Different than removal!

class Crb undef_method :to_send

Interesting that the default output of to_s is present in the output.

columbusrb.to_s

Undefine the Redefine Different than removal!

class Crb undef_method :to_send

Interesting that the default output of to_s is present in the output.

columbusrb.to_sNoMethodError: undefined method `to_s' for #<Crb:0x101651538>

Definitely Undefinedclass String undef_method :to_send

Note that the undef also applied to subclasses of the type where the undef happened.

Definitely Undefinedclass String undef_method :to_send

"rails".to_sNoMethodError: undefined method `to_s' for "rails":String

Note that the undef also applied to subclasses of the type where the undef happened.

Defined Elsewhereclass Crb undef_method :object_idend

The undef succeeds because the method is available to class Crb.

Defined Elsewhereclass Crb undef_method :object_idend

columbusrb = Crb.newcolumbusrb.object_idNoMethodError: undefined method `object_id' for #<Crb:0x10166d7d8>

The undef succeeds because the method is available to class Crb.

Method Removalremove_method :symbol

Removed from the specific type only.

Ruby still searches up the hierarchy.

undef_method :symbolPrevents calls to the method regardless of the type’s hierarchy.

Both defined in the Module class.

Finer Points(pun intended)

You can call remove_method only on a method actually defined within the class itself.

You can call undef_method on a method accessible from the class (inherited or mixed in).

Recommended