58
Ruby 程式語言 20分鐘簡介 [email protected] 2009/4/17 OSDC.TW 2009年4月17日星期五

Ruby 程式語言簡介

  • View
    34

  • Download
    3

Embed Size (px)

DESCRIPTION

 

Citation preview

  • Ruby 20

    [email protected]/4/17

    OSDC.TW

    2009417

  • ? a.k.a. ihower

    http://ihower.idv.tw/blog/ twitter: ihower

    2006 Ruby () Rails Developer

    http://handlino.com http://registrano.com

    2009417

  • Ruby?

    Yukihiro Matsumoto, a.k.a. Matz

    Lisp, Perl, Smalltalk Happy

    2009417

  • # "UPPER"puts "upper".upcase # -5 puts -5.abs # "Ruby Rocks!" 5.times do puts "Ruby Rocks!"end

    2009417

  • Methodsdef end

    def say_hello(name) result = "Hi, " + name return resultend

    puts say_hello('ihower')# Hi, ihower

    2009417

  • Methodsdef end

    def say_hello(name) result = "Hi, " + name return resultend

    puts say_hello('ihower')# Hi, ihower

    2009417

  • Class class Greeter

    def initialize(name) @name = name end def say(word) puts "#{phrase}, #{@name}" end end

    g1 = Greeter.new("ihower")g2 = Greeter.new("ihover") g1.say("Hello") # Hello, ihowerg2.say("Hello") # Hello, ihover

    2009417

  • Class class Greeter

    def initialize(name) @name = name end def say(word) puts "#{phrase}, #{@name}" end end

    g1 = Greeter.new("ihower")g2 = Greeter.new("ihover") g1.say("Hello") # Hello, ihowerg2.say("Hello") # Hello, ihover

    2009417

  • Class class Greeter

    def initialize(name) @name = name end def say(word) puts "#{phrase}, #{@name}" end end

    g1 = Greeter.new("ihower")g2 = Greeter.new("ihover") g1.say("Hello") # Hello, ihowerg2.say("Hello") # Hello, ihover

    2009417

  • Class class Greeter

    def initialize(name) @name = name end def say(word) puts "#{phrase}, #{@name}" end end

    g1 = Greeter.new("ihower")g2 = Greeter.new("ihover") g1.say("Hello") # Hello, ihowerg2.say("Hello") # Hello, ihover

    2009417

  • Class ()class Greeter

    @@name = ihower def self.say puts @@name end end

    Greeter.say # Hello, ihower

    2009417

  • Class ()class Greeter

    @@name = ihower def self.say puts @@name end end

    Greeter.say # Hello, ihower

    2009417

  • Class ()class Greeter

    @@name = ihower def self.say puts @@name end end

    Greeter.say # Hello, ihower

    2009417

  • Arraya = [ 1, "cat", 3.14 ]

    puts a[0] # 1puts a.size # 3

    a[2] = nilputs a.inspect # [1, "cat", nil]

    2009417

  • Hash

    config = { "foo" => 123, "bar" => 456 }

    puts config["foo"] # 123

    2009417

  • Symbols

    config = { :foo => 123, :bar => 456 }

    puts config[:foo] # 123

    2009417

  • If

    if account.total > 100000 puts "large account"elsif account.total > 25000 puts "medium account"else puts "small account"end

    2009417

  • If

    if account.total > 100000 puts "large account"elsif account.total > 25000 puts "medium account"else puts "small account"end

    Perl Style

    2009417

  • Case

    case name when "John" puts "Howdy John!" when "Ryan" puts "Whatz up Ryan!" else puts "Hi #{name}!"end

    2009417

  • false nil

    puts "not execute" if nilputs "not execute" if false

    puts "execute" if true # executeputs "execute" if # execute (JavaScript)puts "execute" if 0 # execute (C)puts "execute" if 1 # executeputs "execute" if "foo" # executeputs "execute" if Array.new # execute

    2009417

  • Regular Expressions Perl

    # phone = "123-456-7890" if phone =~ /(\d{3})-(\d{3})-(\d{4})/ ext = $1 city = $2 num = $3end

    2009417

  • code block closure

    { puts "Hello" } # block

    do puts "Blah" # block puts "Blah"end

    2009417

  • code block(iterator)

    # peoplepeople = ["David", "John", "Mary"]people.each do |person| puts personend # 5.times { puts "Ruby rocks!" }

    # 1.upto(9) { |x| puts x }

    2009417

  • code block(iterator)

    # peoplepeople = ["David", "John", "Mary"]people.each do |person| puts personend # 5.times { puts "Ruby rocks!" }

    # 1.upto(9) { |x| puts x }

    while, until, for

    2009417

  • code block

    # a = [ "a", "b", "c", "d" ]b = a.map {|x| x + "!" } # ["a!", "b!", "c!", "d!"]

    # [1,2,3].find_all{ |x| x % 2 == 0 }# [2]

    2009417

  • code block

    # a = [ "a", "b", "c" ]a.delete_if {|x| x >= "b" }# ["a"]

    # [2,1,3].sort! { |a, b| b a }# ["3",2,1]

    2009417

  • code block functional programming fu?

    # (5..10).inject {|sum, n| sum + n }

    # find the longest wordlongest = ["cat", "sheep", "bear" }.inject do |memo, word| ( memo.length > word.length )? memo : wordend

    2009417

  • code block

    file = File.new("testfile", "r")# ...file.close

    File.open("testfile", "r") do |file| # ...end#

    2009417

  • Yield yield code block

    # def call_block puts "Start" yield yield puts "End"end call_block { puts "Blocks are cool!" }# # "Start" # "Blocks are cool!" # "Blocks are cool!" # "End"

    2009417

  • code blockdef call_block yield(1) yield(2) yield(3)end call_block { |i| puts "#{i}: Blocks are cool!"}# # "1: Blocks are cool!" # "2: Blocks are cool!"# "3: Blocks are cool!"

    2009417

  • Proc object code block

    def call_block(&block) block.call(1) block.call(2) block.call(3)end call_block { |i| puts "#{i}: Blocks are cool!" }

    # proc objectproc_1 = Proc.new { |i| puts "#{i}: Blocks are cool!" }proc_2 = lambda { |i| puts "#{i}: Blocks are cool!" }

    call_block(&proc_1)call_block(&proc_2)

    # # "1: Blocks are cool!" # "2: Blocks are cool!"# "3: Blocks are cool!"

    2009417

  • Module Mixinsmodule Debug def who_am_i? "#{self.class.name} (\##{self.object_id}): #{self.to_s}" endend

    class Foo include Debug # Mixin # ...end

    class Bar include Debug include AwesomeModule # ...end

    ph = Foo.new("12312312")et = Bar.new("78678678")ph.who_am_i? # "Foo (#330450): 12312312"et.who_am_i? # "Bar (#330420): 78678678"

    2009417

  • Module Mixinsmodule Debug def who_am_i? "#{self.class.name} (\##{self.object_id}): #{self.to_s}" endend

    class Foo include Debug # Mixin # ...end

    class Bar include Debug include AwesomeModule # ...end

    ph = Foo.new("12312312")et = Bar.new("78678678")ph.who_am_i? # "Foo (#330450): 12312312"et.who_am_i? # "Bar (#330420): 78678678"

    Ruby Module

    2009417

  • (duck typing)

    # class Duck def quack puts "quack!" endend # ()class Mallard def quack puts "qwuaacck!! quak!" endend

    2009417

  • Class Type

    birds = [Duck.new, Mallard.new, Object.new]

    # ()birds.each do |duck| duck.quack if duck.respond_to? :quackend

    2009417

  • Class Type

    birds = [Duck.new, Mallard.new, Object.new]

    # ()birds.each do |duck| duck.quack if duck.respond_to? :quackend

    OOP!

    2009417

  • Metaprogramming

    2009417

  • define_method

    class Dragon define_method(:foo) { puts "bar" }

    ['a','b','c','d','e','f'].each do |x| define_method(x) { puts x } endend

    dragon = Dragon.newdragon.foo # "bar"dragon.a # "a"dragon.f # "f"

    2009417

  • Domain-Specific Language

    class Firm < ActiveRecord::Base has_many :clients has_one :account belongs_to :conglomorateend

    # has_many AciveRecord class method# Firm instance methods

    firm = Firm.find(1)firm.clientsfirm.clients.sizefirm.clients.buildfirm.clients.destroy_all

    2009417

  • Method Missingclass Proxy def initialize(object) @object = object end def method_missing(symbol, *args) @object.send(symbol, *args) endend object = ["a", "b", "c"]proxy = Proxy.new(object)puts proxy.first # Proxy first method_missing "a"

    2009417

  • Introspection ()

    # Object.methods=> ["send", "name", "class_eval", "object_id", "new", "singleton_methods", ...] # Object.respond_to? :name=> true

    2009417

  • Ruby on Rails 5

    [email protected]/4/17

    OSDC.TW

    2009417

  • Rails? Web

    database-backed

    Model-View-Control () Ruby

    AjaxORM (object-relational-mapping)

    2004 David Heinemeier Hanson(DHH) 37signals

    2009417

  • Dont Repeat Yourself

    Convention Over Configuration

    Ruby

    2009417

  • Rails

    2005 DHH Hacker 2006 Rails Jolt 2005~2006 Ruby/Rails 1552%

    Ruby Tiobe 26 10

    2009417

  • Rails ?Java(Spring/Hibernate) Rails

    420 4(5)

    3293 1164

    1161 113

    / 62/549 55/126

    Justin Gehtland Java Rails

    2009417

  • Rails ?

    Justin Gehtland Java :Rails = 3.5 : 1 Proc.net PHP : Rails = 10 : 1 JavaEye JAVA : Rails = 10 : 1 thegiive PHP : Rails = 8 : 1

    2009417

  • Rails clone

    2009417

  • Why Ruby?

    20% Java 300%

    From Beyond Java

    2009417

  • Rails

    C

    M

    V

    2009417

  • DB schema Ruby

    class CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name t.integer :age t.date :birthday t.text :bio t.timestamps end end

    def self.down drop_table :people endend

    2009417

  • Active RecordORM

    class Person < ActiveRecord::Base # end

    person = Person.newperson.name "ihower"person.age = 18person.save

    person = Person.find(1)puts person.name # ihower

    2009417

  • Action Controller HTTP request

    class PeopleController < ApplicationController

    # GET /people def index @people = Person.all end end

    2009417

  • Action Controller HTTP request

    class PeopleController < ApplicationController

    # GET /people def index @people = Person.all end end

    method action

    2009417

  • Action Controller HTTP request

    class PeopleController < ApplicationController

    # GET /people def index @people = Person.all end end

    instance variable View

    method action

    2009417

  • Action View Ruby HTML

    Guestbook :

    2009417

  • MVCModel-View-Control

    route.rbHTTP requestGET /users/1

    Browser

    UsersController

    end

    def show@user = User.find(params[:id])

    respond_to do |format|format.htmlformat.xml

    endend

    def index......

    end

    Model

    Database

    #show.html.erb

    User Profile

    View

    Controller Action

    2009417

  • Thank you.

    Programming Ruby (The Pragmatic Programmers)Ruby (OReilly)Get to the Point! (http://johnwlong.com/slides/gettothepoint/)Ruby on Rails slide by thegiive in COSCUP

    2009417