Ruby/Rails syntax
  • Index
  • chap 1
  • chap 2
  • chap 3
  • chap 4
  • Enterprise Rails - big picture
  • Nokogiri
  • ActiveRecord - 進階功能
  • pack & unpack
  • performance
  • rails engine
  • jsonb / json / hstore
  • Deploy
  • Polymorphism/Polymorphic Associations
  • relationship
  • rvm / ENV
  • Auth
  • DB related
  • TODO N+1
  • SQL view
  • module
  • api + create-react-app
  • ONE_LINE
  • Delete & destroy association
Powered by GitBook
On this page
  • attr_*
  • virtual attribute/ setter / :method=
  • use var & @var in class
  • &:symbol
  • define_method(*args)
  • constantize(str)
  • Inject and Reduce
  • File
  • const_get / send (fetch class/method by "string" or :sym)
  • include / extend

Was this helpful?

chap 1

attr_*

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

  1. With attr_reader inside class, you can use both element & @element.

  2. 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" }
# people.collect { |p| p.name }
people.collect(&:name)

# people.select { |p| p.manager? }.collect { |p| p.salary }
people.select(&:manager?).collect(&:salary)

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"
(1..10).inject(:+) # 55
(1..10).reduce(:+) # 55

def sum(start = 0)
  inject(start, &:+)
end
(1..10).sum # 55

File

__FILE__ # the current source file name.
__LINE__ # the current line number in the source file.
File.dirname(__FILE__) # "."
File.expand_path(File.dirname(__FILE__))
# /Users/jasonych99/workspace/ROR/RULER/rulers
File.join(File.dirname(__FILE__), "..", "lib") # "./../lib"

The second param is the starting point for the first one in File.expand_path.

File.expand_path(__FILE__)
 => "/Users/jasonych99/workspace/ROR/RULER/rulers/(irb)"
File.expand_path("../../assets/base.css", __FILE__)
 => "/Users/jasonych99/workspace/ROR/RULER/assets/base.css"

$0 = name of the script being executed.

For example, when running ruby hello_world.rb, $0 = hello_world.

__FILE__ == $0 
# the source code file == the file I'm executing!

const_get / send (fetch class/method by "string" or :sym)

check and return the constant

const_get(:sym)
const_get("string")
Math.const_get(:PI)   #=> 3.14159265358979

Invoke the method

obj.send(:sym)
obj.send("string")
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>
PreviousIndexNextchap 2

Last updated 5 years ago

Was this helpful?

reference:

http://periclestheo.com/2014/02/what-is-up-with-__FILE__-and-$0.html