The extend method works similar to include, but unlike include, you can use it to extend any object by including methods and constants from a module. It can add class level methods - something that include can't do.
module Foo
def say_hi
puts "Hi!"
end
end
class Bar
end
Bar.extend Foo
Bar.say_hi
add all the module instance methods as module functions
module Foo
extend self
def foo
end
end
p Foo.foo.
Mimick "include" with "extend"
module Foo
def method_in_module
"The method defined in the module invoked"
end
end
class Bar
def initialize
self.extend Foo
end
end
take all parameters and put it into an array
def my_method(*name)
transform an array in object : hoge(1.2.3)
arr = [1,2,3]
hoge(*arr)
def hello
yield if block_given?
end
hello do
puts "hello"
end
is similar to :
def hello
yield if block_given?
end
#with lambda
blah = ->{puts "hello"}
hello(&blah)
The Comparable mixin is used by classes whose objects may be ordered. The class must define the <=>
class SizeMatters
include Comparable
attr :str
def <=>(anOther)
str.size <=> anOther.str.size
end
def initialize(str)
@str = str
end
def inspect
@str
end
end
s1 = SizeMatters.new("Z")
s2 = SizeMatters.new("YY")
s3 = SizeMatters.new("XXX")
s4 = SizeMatters.new("WWWW")
s5 = SizeMatters.new("VVVVV")
s1 < s2 #=> true
s4.between?(s1, s3) #=> false
s4.between?(s3, s5) #=> true
[ s3, s2, s5, s4, s1 ].sort #=> [Z, YY, XXX, WWWW, VVVVV]
as simple operator
Combined comparison operator. Returns 0 if first operand equals second, 1 if first operand is greater than the second and -1 if first operand is less than the second.
def hello(&block)
block.call if block_given?
end
class Item
def self.show
puts "Class method show invoked"
end
end
class Item
class << self
def show
puts "Class method show invoked"
end
end
end
class Planet
@@planets_count = 0
end
p Planet.planets_count
book = Book.new("Programming Ruby")
book.instance_variable_set(:@title, "Programming Ruby 1.9")
Returns the value of the given instance variable, or nil if the instance variable is not set.
def inspect_instance_variable(class_name, variable)
Module.const_get(class_name).new.instance_variable_get("@" + variable)
end
class Fred
def initialize(p1, p2)
@a, @b = p1, p2
end
end
fred = Fred.new('cat', 99)
fred.instance_variable_get(:@a) #=> "cat"
fred.instance_variable_get("@b") #=> 99
Checks for a constant with the given name
Math.const_get(:PI) #=> 3.14159265358979
def inspect_instance_variable(class_name, variable)
Module.const_get(class_name).new.instance_variable_get("@" + variable)
end
Method | function |
---|---|
parameters | Returns all the parameters that the method is defined withd |
arity | Returns a Fixnum representing the number of arguments that the method can accept is used |
method | Returns the Method object |
def monk(arg1, *args2)
"Monks" + arg1 + args2.first
end
mo = self.method(:monk)
puts "Arity"
p mo.arity
puts "Parameters"
p mo.parameters
String.class_eval do
def get_size
length
end
end
class String
def get_size
length
end
end
class << someinstance
def foo
"Hello."
end
end
We can use alias for keeping overriden method
alias old_my_greeting my_greeting
One major benefit of this is that you can reduce the duplication inherent methods with similar definitions.
class Doctor
["rhinoplasty", "checkup", "interpretive_dance"].each do |action|
define_method("perform_#{action}") do |argument|
"performing #{action.gsub('_', ' ')} on #{argument}"
end
end
end
doctor = Doctor.new
puts doctor.perform_rhinoplasty("nose")
puts doctor.perform_checkup("throat")
puts doctor.perform_interpretive_dance("in da club")
Define a class method
monk = Class.new
monk.class_eval do
def zen
42
end
end
p Module.const_get('monk').new.zen
Used with block
class ChefDSL
def template(path, &block)
TemplateDSL.new(path, &block)
end
end
class TemplateDSL
def initialize(path, &block)
@path = path
instance_eval &block
end
def source(source); @source = source; end
def owner(owner); @owner = owner; end
def mode(mode); @mode = mode; end
end
...
template "/path/to/file.conf" do
source "file.conf.erb"
owner "trotter"
mode "0755"
end
Define an instance method , Evaluates a string containing Ruby source code
class That
end
p Module.const_get('This').new
class Monk
eval "def zen; end"
end
Evaluating code read out of a file or a string coming from a database greatly increases the risk of execution of malicious code and is one of the reasons why eval is considered evil.
Evaluates the given block in the context of the class/module
class Thing
end
Thing.class_exec{
def hello() "Hello there!" end
}
puts Thing.new.hello()
Called when a non existing method is called
class ActiveRecord::Base
def method_missing(meth, *args, &block)
if meth.to_s =~ /^find_by_(.+)$/
run_find_by_method($1, *args, &block)
else
super # You *must* call super if you don't handle the
# method, otherwise you'll mess up Ruby's method
# lookup.
end
end
Invoked when a reference is made to an undefined constant in mod
def Foo.const_missing(name)
name # return the constant name as Symbol
end
Foo::UNDEFINED_CONST #=> :UNDEFINED_CONST: symbol returned
class Klass
def hello(*args)
"Hello " + args.join(' ')
end
end
k = Klass.new
k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
It can add class level methods - something that "include" can't do.
module Foo
def say_hi
puts "Hi!"
end
end
class Bar
end
Bar.extend Foo
Bar.say_hi
module Foo
def self.included(klass)
klass.extend ClassMethods
end
module ClassMethods
def guitar
"gently weeps"
end
end
end
class Bar
include Foo
end
puts Bar.guitar
Method | function |
---|---|
method_addded | when a new method is added with add_method |
method_removed | When remove_method is used |
singleton_method_added | |
singleton_method_removed | |
method_undefined | When an undefined method is called |
included | When a module is included |
ex for included :
module Foo
def self.included(klass)
puts "Foo has been included in class #{klass}"
end
end
class Bar
include Foo
end
module Gym
def self.included(class_or_module)
class_or_module.send(:include, InstanceMethods)
class_or_module.extend(ClassMethods)
end
module ClassMethods
def build
end
end
module InstanceMethods
def open
end
def book_for_practice
end
def close
end
end
end
module HashInitialized
def hash_initialized(*fields)
define_method(:initialize) do |h|
missing = fields - h.keys
raise Exception, "Not all fields set: #{missing}" if missing.any?
h.each do |k,v|
instance_variable_set("@#{k}", v) if fields.include?(k)
end
end
end
end
class Cheese
extend HashInitialized
attr_accessor :color, :odor, :taste
hash_initialized :color, :odor, :taste
end
class Object
def not
Not.new(self)
end
class Not
def initialize(original)
@original = original
end
def method_missing(sym, *args, &blk)
!@original.send(sym, *args, &blk)
end
end
end
class Person
def initialize(name)
@name = name
end
def smith?
@name == "Smith"
end
end
puts Person.new("Ziggy").not.smith?
require 'benchmark'
class Monk
eval "def zen; end"
define_method(:zen_block) {}
end
monk = Monk.new
Benchmark.bmbm do |x|
x.report("eval zen: ") { 10_000.times { monk.zen } }
x.report("define_method zen: ") { 10_000.times { monk.zen_block } }
end
class Symbol
def for(&sblk)
if self == :meditate
Calculate.new.instance_eval(&sblk)
end
end
end
class Calculate
end
class Monks
class << self
def should(&sblk)
self.new.instance_eval(&sblk)
end
end
end
Monks.should do
:meditate.for do
puts "5 seconds"
end
end
class Callbacker
def make_callback(obj, meth)
metaclass = class << self; self; end
metaclass.send(:define_method, :callback) do
obj.send(meth)
end
end
end
# usage
callbacker = Callbacker.new
callbacker.make_callback(" hello ", :strip)
callbacker.callback # => "hello"