attr_accessor :engine allows you to read AND write to the variable @engine.
attr_reader :engine only allows you to read the value of @engine
attr_writer :age
# up is equal to bottom.
def age=(value)
@age = value
end
attr_reader :age
# up is equal to bottom.
def age
@age
end
attr_accessor :age
# up is equal to bottom.
def age=(value)
@age = value
end
def age
@age
end
virtual attribute/ setter / :method=
:method= assign attributes by =
:method assign attributes by ()
class Foo
def foo=(x)
puts "OK: x=#{x}"
end
def poo(y)
puts "KO: y=#{y}"
end
end
f = Foo.new
f.foo = 123 # => 123
# OK: x=123
f.poo(123)
# KO: y=123
use var & @var in class
With attr_reader inside class, you can use both element & @element.
Without attr_reader inside class, you can use only @element.
class Person
attr_reader :element # make different
def initialize(element)
@element = element
end
def at
puts @element
end
def woat
puts element
end
end
gina = Person.new("Gina")
gina.at # Gina
gina.woat # Gina
class People
def initialize(element)
@element = element
end
def at
puts @element
end
def woat
puts element
end
end
jason = People.new("Jason")
jason.at # Jason
jason.woat # rb:12 undefined local variable or method `element'
&:symbol
block: {...} or do ... end
Proc: set block as a variable.
&Proc: return the original block.
my_proc = Proc.new { puts "foo" }
# => #<Proc:0x0012345677(irb):99>
my_method_call(&my_proc) # is identical to:
my_method_call { puts "foo" }
Difference between Proc and lambda:
1. lambda checks argument numbers, and Proc not.
2. return in lambda means "leaving lambda"; return in Proc means "leaving the method.
define_method(*args)
Defines an instance method for the receiver: args.
class A
def fred
puts "In Fred"
end
def create_method(name, &block)
self.class.send(:define_method, name, &block)
end
define_method(:wilma) { puts "Charge it!" }
end
class B < A
define_method(:barney, instance_method(:fred))
end
a = B.new
a.barney
a.wilma
a.create_method(:betty) { p self }
a.betty
In Fred
Charge it!
#<B:0x401b39e8>
constantize(str)
tries to find a declared constant with the name specified in the string.
'Module'.constantize # => Module
'Class'.constantize # => Class
'blargle'.constantize # => NameError: wrong constant name blargle
Inject and Reduce
Inject and Reduce are the same.
# Sum some numbers
(5..10).reduce(:+) #=> 45
# Same using a block and inject
(5..10).inject {|sum, n| sum + n } #=> 45
# Multiply some numbers
(5..10).reduce(1, :*) #=> 151200
# Same using a block
(5..10).inject(1) {|product, n| product * n } #=> 151200
# find the longest word
longest = %w{ cat sheep bear }.inject do |memo,word|
memo.length > word.length ? memo : word
end
longest #=> "sheep"
class Person
def initialize(name)
@name = name
end
def name
@name
end
def oui
"My name is #{@name}"
end
end
target = Object.const_get("Person") # Person
target.class # Class
obj = Person.new("Jason") # #<Person:0x007f9012999248 @name="Jason">
obj.oui # "My name is Jason"
obj.send(:oui) # "My name is Jason"
obj.send("oui") # "My name is Jason"
include / extend
include provides instance methods for the class that mixes it in.
extend provides class methods for the class that mixes it in.
module Foo
def foo
puts 'heyyyyoooo!'
end
end
class Bar
include Foo
end
Bar.new.foo # heyyyyoooo!
Bar.foo # NoMethodError: undefined method ‘foo’ for Bar:Class
class Baz
extend Foo
end
Baz.foo # heyyyyoooo!
Baz.new.foo # NoMethodError: undefined method ‘foo’ for #<Baz:0x1e708>