• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content

Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Like this presentation? Why not share!

Rubyist九州ruby入門勉強会

on

  • 2,025 views

 

Statistics

Views

Total Views
2,025
Views on SlideShare
2,021
Embed Views
4

Actions

Likes
0
Downloads
8
Comments
0

1 Embed 4

http://dev.localhost 4

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Rubyist九州ruby入門勉強会 Rubyist九州ruby入門勉強会 Presentation Transcript

    • Ruby 入門勉強会 ( Ruby の魅力を知る) Rubyist 九州 山崎重一郎
    • オープンソース
      • 世の中にあるものが気に入らなかったら
      • 自分でもっといいものを作ってしまえばいい
      • Ruby の作者 -> まつもとゆきひろ氏
      ただ、開発にあたって大事にしてきたことはあります。それは、自分が欲しいものを作ること。僕は短気で(笑)。だから、自分がイライラしないものを作りたかった。シンプルで、わかりやすいもの。誰に気に入ってもらおうとか、使ってもらおうとか、そういうものではない。自分が使いたいもの。誰かのために役立つという利他的精神は、ないわけではないけれど、自分ではあまり意識してないですね。それよりも、圧倒的に自分がイライラしなくてすむという利己的精神のほうが強い(笑)。
    • オープンソース
      •   Ruby = まつもとさんにとっての理想の言語
        • 自分がほしい理想の車、
        • 自分がほしい理想の携帯端末
        • 自分がほしい理想のクラウド、 ...
      • ナショナリズム的な意味ではなく、やっぱり日本人のエンジニアが自然にほしがる言語処理系という感じ
      • 「クールジャパン」なんて政府が音頭とると「逆宣伝やめて」とおもうけど、世界中の人が率直にクールと感じる日本製の感覚と共通点があるとおもう
    • 理想の言語って?
      • 用途によって違う
      • 使う人のバックグラウンドや価値観によって違う
      • 時代によって変化する
      理想の車?
    • 僕が想う理想の言語
      • 学ぶのが難しくない
      • さくっと気持ち良く書けて読みやすい
      • 「生態系」が豊かで育てるコミュニティがいい
      • 「使いたい」と思うキラーアプリがある
    • 僕が想う理想の言語
      • 学ぶのが難しくない
      • さくっと気持ち良く書けて読みやすい
      • 「生態系」が豊かで育てるコミュニティがいい
      • 「使いたい」と思うキラーアプリがある
    • 学ぶのが難しくない
        • 手続き型言語
          • 手続きで処理を書いていく(わかりやすい)
        • オブジェクト指向言語
          • 大規模開発や仕様を洗練させるのにむいている
          • (最初はわかりにくいけど、慣れれば便利)
        • 関数型言語
          • 分散処理や仕様のテストに適している
          • (関数脳になるまでちょっとたいへん。でも今後は必須?)
      • Ruby は何型言語か?
      •  手続き型、オブジェクト指向、関数型、どれも OK
    • ちょっと動かしてみる
      • サンプルデータ (people.csv)
        • Twitter のランダムに選択した 28830 人のユーザ情報
        • フォロワーのフォロワーをランダムに 4 人ずつ 8 ホップ
        • csv 形式にしている
      id,name,screen_name,time_zone,location,favourites_count,followers_count,friends_count,statuses_count 85259796,DEVO,DEVO,Pacific Time (US & Canada),United States,0,16237,372,272 101615606, ひで ,yamahide1973,Tokyo, 東京23区 ,1,8559,9406,480 14485987, かろしま かろあき ,karoshima,Tokyo,iPhone: 35.567738;139.642487,53,37,28,1130 117276911,JOJO 広重 ,jojo_hiroshige,Tokyo, あの橋を渡って ,1,1785,80,827 19733819,Direct Mail CRM,DirectMailCRM,Pacific Time (US & Canada),Vancouver; BC,22,17982,18338,317 126901360,mituhiro,mitti2525,nil, 福岡市 ,577,1947,2086,1295 91584317,Yoichi Kato,DRIVING_MAUL,Tokyo, 中目黒 or 東急田園都市線沿線 ,5,203,159,752 19314650,Chuck Palahniuk,chuckpalahniuk,Pacific Time (US & Canada),Los Angeles,1,257790,22,826
    • 手続き型言語としての Ruby (文法の説明は次回。何となく見て!)
      • 直感がはたらく
        • 初めての言語が C や Java などの手続き型言語の人なら特に
        • 副作用があってもわかっててやる分には気にしない
      $ irb1.9 Ruby1.9 インタプリタの起動 > lines = File.readlines('people.csv') #csv ファイルの読み込み配列に > csv = lines.map {|line| line.chomp.split(',')} # ',' で分割した配列にする > keys = csv.shift #1 行目を取り出して削除する #csv の内容を項目名を使ったハッシュの配列に変換する > csv_ha = csv.map {|p| Hash[keys.map.with_index {|k,i| [k,p[i]]}]} > csv_ha[0] => {"id"=>"85259796", "name"=>"DEVO", "screen_name"=>"DEVO", "time_zone"=>"Pacific Time (US & Canada)", "location"=>"United States", "favourites_count"=>"0", "followers_count"=>"16237", "friends_count"=>"372", "statuses_count"=>"272"}
    • 手続き型言語としての Ruby
      • # おまけ  map reduce で Twitter ユーザのタイムゾーンを集計
      • > proj = csv_ha.map {|p| [p["time_zone"],1]} # タイムゾーン情報を map で抽出
      • # reduce でタイムゾーンごとに集計
      • > tz = proj.reduce(Hash.new(0)) {|h,z| h[z[0]]=h[z[0]]+1; h}
      • > tz.to_a.sort_by {|d| d[1]}.reverse # 人数が多い順にソート
      • #  サンプルファイルは、実際に集めた 28829 人分の Twitter ユーザ情報
      • => [["Tokyo", 13464], ["nil", 3317], ["Hawaii", 2690], ["Osaka", 1729], ["Eastern Time (US & Canada)", 1672], ["Pacific Time (US & Canada)", 1498], ["Central Time (US & Canada)", 851], ["Quito", 462], ["Beijing", 447], ["London", 418], ["Alaska", 264], ["Sapporo", 255], ["Berlin", 249], ["Mountain Time (US & Canada)", 194], ["Sydney", 115], ["Greenland", 101], ["Melbourne", 95], ["Hong Kong", 94], ["Brasilia", 57], ["Paris", 51], ["Seoul", 43], ["Brisbane", 38], ["Arizona", 37], ["Amsterdam", 37], ...
    • オブジェクト指向言語としての Ruby
      • かなりきっちりしたオブジェクト指向言語
      • (「オブジェクト指向とは」の話はしません)
        • Ruby のオブジェクトは強く型づけされている
          • 変数には型がなく、宣言なしで使える
        • たくさんの組み込みクラスがある
          • クラス構成はフラットでライブラリはコンパクト
        • クラスは必ずしも作らなくてもいい
          • オブジェクトに直接メソッドを定義することもできる
    • オブジェクト指向言語としての Ruby
      • class CSV # クラス定義
      • def initialize(file)
      • File.open(file) {|f| @csv = f.reduce([]) {|a,l| a << l.chomp.split(',')}}
      • @keys = @csv.shift # インスタンス変数を格納
      • end
      • # ハッシュの配列変換メソッド定義
      • def to_ha
      • @csv.map {|p| Hash[@keys.map.with_index {|k,i| [k,p[i]]}]}
      • end
      • # map reduce でキーごとの頻度を多い順に表示
      • def histgram(key)
      • self.to_ha. map {|p| [p[key],1]}. reduce (Hash.new(0)) {|h,z| h[z[0]]=h[z[0]]+1; h}.to_a.sort_by {|d| d[1]}.reverse
      • end
      • end
    • オブジェクト指向言語としての Ruby
      • > csv = CSV.new('people.csv') #CSV ファイルからインスタンス作成
      • > csv_ha = csv.to_ha # ハッシュの配列に変換する
      • > csv.class #csv というオブジェクトのクラスは?
      • => CSV
      • > csv.methods #csv というオブジェクトが持つメソッド
      • => [:to_ha, :nil?, :===, :=~, :!~, :eql?, :class, :clone, :dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :t
      • ...
      • :hash, :__id__, :object_id, :to_enum, :enum_for, :gem, :==, :equal?, :!, :!=, :instance_eval, :instance_e xec, :__send__]
      • > csv.instance_variables #csv オブジェクトのインスタンス変数
      • => [:@csv, :@keys]
      • > csv.object_id #csv オブジェクトのオブジェクト ID
      • => 2198221200
    • オブジェクト指向言語としての Ruby
      • > csv.histgram('time_zone') # タイムゾーンごとの頻度の集計
      • => [[&quot;Tokyo&quot;, 13464], [&quot;nil&quot;, 3317], [&quot;Hawaii&quot;, 2690], [&quot;Osaka&quot;, 1729], ...]
      • > csv.histgram('followers_count') # フォロワー数ごとの頻度の集計
      • => [[&quot;6&quot;, 127], [&quot;5&quot;, 126], [&quot;4&quot;, 125], [&quot;9&quot;, 123], [&quot;2&quot;, 122], [&quot;7&quot;, 120], [&quot;3&quot;, 118], [&quot;12&quot;, 117], [&quot;1&quot;, 116], [&quot;14&quot;, 116], [&quot;11&quot;, 115], [&quot;17&quot;, 106], [&quot;15&quot;, 105], [&quot;22&quot;, 102], [&quot;18&quot;, 102], [&quot;21&quot;, 101],
      • ...
      • ]
    • オブジェクト指向言語としての Ruby
      • mix-in 継承  =  形容詞のようにメソッドだけ追加
      class Shain include Comparable # 比較可能な〜 Shain # 順序関係は、平社員 < 課長 < 部長 < 専務 < 社長 POSTS = {' 平社員 '=>0, ' 課長 '=>1, ' 部長 '=>2, ' 専務 '=>3, ' 社長 '=>4} attr :post def initialize(post) @post = post end def <=>(other) POSTS[self.post] <=> POSTS[other.post] end end
    • オブジェクト指向言語としての Ruby
      • mix-in 継承
      > s1=Shain.new(' 課長 ') > s2=Shain.new(' 平社員 ') > s3=Shain.new(' 平社員 ') > s4=Shain.new(' 社長 ') > list = [s1,s2,s3,s4] list = [s1,s2,s3,s4] => [#<Shain:0x000001009bcb78 @post=&quot; 課長 &quot;>, #<Shain:0x000001009ac418 @post=&quot; 平社員 &quot;>, #<Shain:0x000001009a6e20 @post=&quot; 平社員 &quot;>, #<Shain:0x000001009a1748 @post=&quot; 社長 &quot;>] > list.sort => [#<Shain:0x000001009a6e20 @post=&quot; 平社員 &quot;>, #<Shain:0x000001009ac418 @post=&quot; 平社員 &quot;>, #<Shain:0x000001009bcb78 @post=&quot; 課長 &quot;>, #<Shain:0x000001009a1748 @post=&quot; 社長 &quot;>]
    • 関数型言語としての Ruby
      • 1.9 になって関数型のにおいがちょっと強くなった
      • 関数型言語とは
        • 「関数」とは入力と出力の対の集合=グラフと考える
          • これは処理や手続きではないと思考する脳が必要
          • 変数には副作用がない(代入は一度きり)
          • 時間の概念がない(評価を遅延させたりできる)
        • 関数自体もデータと同列に扱える
      • Ruby の場合
        • ブロックは関数じゃなくて手続きだけど、 Proc オブジェクトというのに変換すると関数(オブジェクト)になる
    • 関数言語としての Ruby
      • > f = {2 + 3} # ブロックはオブジェクトじゃない
      • SyntaxError: (irb):39: syntax error, unexpected '}', expecting tASSOC
      • > f = lambda {2 + 3} # lambda ってつけると Proc オブジェクトになる
      • => #<Proc:0x000001009a0f68@(irb):13 (lambda)>
      • > f.call # call メソッドで関数が評価される(それまで評価が遅延される)
      • => 5
      • > f = lambda {|x| 2*x + 3} # 引数付きの場合
      • => #<Proc:0x00000100995770@(irb):15 (lambda)>
      • > f.call(10) #call の引数で引数を渡す
      • => 23
      • > g= lambda {|f| f.call(10)} # 関数を引数にする関数の定義
      • => #<Proc:0x00000100961b08@(irb):17 (lambda)>
      • > g.call(f) # call の引数に関数を入れて評価
      • => 23
    • ラムダ? 
      • 数学の関数の式の定数と変数の違いってなに?
      •       ax + b
      • 先生:「 a と b は定数で x は変数じゃ」(なんで?)
      • 「これが変数」ってはっきりさせるために λ (ラムダ)を付ける
      • λx (ax + b)
      • ( xを束縛変数と a,b を自由変数と呼びます)
    • ギリシャ文字恐怖症
      • 数学の実際の難しさ以上にギリシャ文字が怖い
      • λ (ラムダ)とか、 lambda ( b を忘れそう〜)
      • でも大丈夫!
      • Ruby1.9 では、 -> で lambda を表せるようになった
      •         lambda {|x| 2*x + 3} は
      •        -> x {2*x + 3}      とかける
      • 僕は「この -> x は束縛変数だぜ!」と感じている
    • 関数言語としての Ruby
      • 変数環境とクロージャ
        • ラムダがついていない自由変数の値を「束縛」する=環境
        • λx (ax + b)  の a や b の値を具体化すること
      > a = 2 # 環境定義 a は2 > b = 3 # 環境定義 b は 3 > f = ->x {a*x + b} # x は束縛変数 > f.call(10) => 23 > b = 7 > f.call(10) => 27
    • 関数言語としての Ruby
      • レキシコン=辞書の中の語彙のこと
        • 環境 = 辞書 自由変数の名前と意味(束縛された値)
        • Ruby は、関数ごとクロージャというオブジェクトを持ち、独立に環境を管理する
        • 関数オブジェクトを生成するメソッドがつくれる
      > def f(a,b) -> x {a*x + b} end # Proc オブジェクトを生成するメソッドを定義 > f23 = f(2,3) # 変数 a,b の値を束縛した Proc オブジェクトを作成 > f23.call(10) #Proc の関数を評価してみる => 23 > f27 = f(2,7) # 変数 a, b を別の値で束縛した Proc オブジェクト > f27.call(10) #Proc の関数を評価してみる => 27 > eval('a', f23.binding) #eval でクロージャの内容を確認 => 2
    • 関数言語としての Ruby
      • レキシカルスコープ
        • クロージャ内部の自由変数を関数が自分の環境で変更できる
      > def cl a=0; -> {a+=1} end # 束縛変数なしの Proc でインクリメント > x = cl #Proc オブジェクトの生成(クロージャも生成される) > x.call => 1 > x.call => 2 > y = f # 新しい Proc オブジェクトの生成(クロージャも生成) > y.call => 1 > eval('a', x.binding) => 2 > eval('a', y.binding) => 1
    • 関数言語としての Ruby
      • 再帰プログラミング( 2 を聞いてnを知る)
        • 停止条件まで自分自身を入れ子的にコピーしてから実行
        • 末尾再帰最適化( TRO) をしないと効率が悪い
        • reduce (inject) を使うと TRO と同じ効果がある
      > def fact(n) n==0 ? 1 : n*fact(n-1) end # 階乗の再帰的定義 > def fact2(n) (1..n).reduce(1) {|fact,i| fact*i} end # 階乗を reduce で定義 # 山崎の環境で > fact(7000) #OK > fact(8000) SystemStackError: stack level too deep > fact2(20000) #OK
    • 関数言語としての Ruby
      • クロージャを使ったキャッシュ = memo 化
        • 関数とは「グラフ」のこと  =  入力と出力の対
        • 一度やった計算はクロージャにメモっておき再計算しない
      > def fact3 c={}; ->x {c[x] ||= (1..x).reduce(1) {|r,i|r*i}; c[x]} end > f = fact3 > f.call(6) => 720 > f.call(10) => 3628800 > eval('c',f.binding) => {6=>720, 10=>3628800}
    • 関数言語としての Ruby
      • 関数は時間を超越している
        • 遅延評価( Lazy evaluation )ができる言語が多い
        • Ruby には遅延評価機構はないが、似たようなことはやろうと思えばできる
      > csv = -> { CSV.new('people.csv') } > ... # なんかいろいろ処理をするけどファイルアクセスはまだしない > data = csv.call
    • 僕が想う理想の言語
      • 学ぶのが難しくない
      • さくっと気持ち良く書けて読みやすい
      • 「生態系」が豊かで育てるコミュニティがいい
      • 「使いたい」と思うキラーアプリがある
    • さくっと気持ち良く書けて読みやすい
      • こうしたら、こうなる。うんうん。
      • こうしたら? あー、やっぱりこうなった!
      > a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] > b = a.shuffle => [4, 1, 10, 8, 6, 5, 2, 7, 3, 9] > b.sort => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] > b.select {|x| x > 5} => [10, 8, 6, 7, 9] > a.map {|x| x*10} => [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
    • さくっと気持ち良く書けて読みやすい
      • 文字列の処理
      > t = ' さくっと ' + 'cool!' => &quot; さくっと cool!&quot; > t[0] => &quot; さ &quot; > t[2..7] => &quot; っと cool&quot; > line = &quot;85259796,DEVO,DEVO,Pacific Time (US & Canada),United States,0,16237,372,272&quot; > line.split(',') => [&quot;85259796&quot;, &quot;DEVO&quot;, &quot;DEVO&quot;, &quot;Pacific Time (US & Canada)&quot;, &quot;United States&quot;, &quot;0&quot;, &quot;16237&quot;, &quot;372&quot;, &quot;272 &quot;] > lines = File.readlines('people.csv') > csv = lines.map {|line| line.chomp.split(',')}
    • さくっと気持ち良く書けて読みやすい
          • あ、なるほどね
      def generation(age) case age when 0..12 then ' 小学生 ' when 13..16 then ' 中学生 ' when 17..18 then ' 高校生 ' when 19..20 then ' 未成年 ' else ' 成人 ' end end > generation(11) => &quot; 小学生 &quot;
    • 僕が想う理想の言語
      • 学ぶのが難しくない
      • さくっと気持ち良く書けて読みやすい
      • 「生態系」が豊かで育てるコミュニティがいい
      • 「使いたい」と思うキラーアプリがある
    • 「生態系」が豊かで育てるコミュニティがいい
      • 土地の値段
        • 交通の利便性、周囲の環境、商業地に近い、 ...  -> 生態系
      • プログラムの価値
        • 顧客へのアピール度、開発コミュニティ、関連システム、
        • ライブラリ、技術情報入手の容易さ、生産性、性能
        • 利用者の人口普及率、 教育、普及広報活動
      • Ruby の生態系、コミュニティ
        • 言語処理系としてはかなりいい方、特に日本
        • Ruby on Rails で生産性が注目され、アピール度が高まった
          • Rubyist 九州も普及にはちょっと貢献している?
    • 「生態系」が豊かで育てるコミュニティがいい
      • ライブラリの利用方法
        • 組み込みライブラリが豊富にある
        • rubygems というツールを使ってネットから
    • 「生態系」が豊かで育てるコミュニティがいい
      • ライブラリの利用方法  (require)
        • twitter のパブリックタイムラインを RESTful API で取得する
      > require 'open-uri' > require 'json' > tl =open('http://api.twitter.com/1/statuses/public_timeline.json').read > timeline = JSON.parse(tl) > timeline.size => 20 > keys = timeline[0].keys > timeline[0][keys[0]]
    • 「生態系」が豊かで育てるコミュニティがいい
      • Ruby は処理速度は速くない
        • 数値計算などの速度重視の処理には適していない
        • C 言語で書かれたプログラムは容易に Ruby から利用できる
        • JRuby を使うと Java とも連携
        • R 言語などとも連携可能
        • 様々な DB と接続できる
    • 「生態系」が豊かで育てるコミュニティがいい
      • R 言語を利用する場合
        • 現時点では、 Ruby1.8.7 を使う方が安全
      ■ 環境変数の設定 export R_HOME=/Library/Frameworks/R.framework/Resources ■ rubygems で rsruby をインストール $ sudo gem install rsruby -- --with-R-include=/Library/Frameworks/R.framework/Headers --with-R-lib=/Library/Frameworks/R.framework/Libraries >require 'rubygems' > require 'rsruby' r = RSRuby::instance r.eval_R(<<-RCOMMAND) # 実行したい R のコード RCOMMANDS
    • 「生態系」が豊かで育てるコミュニティがいい
      • R 言語を利用する場合
      ■ 例 require 'rubygems' require 'rsruby' r = RSRuby::instance xr=[*1..1000] yr = xr.map {|a| a**2} g=r.eval_R(<<-RCOMMANDS) pdf(&quot;graph.pdf&quot;) x <- matrix(c(#{xr.join(',')}), 1, #{xr.size}) y <- matrix(c(#{yr.join(',')}), 1, #{yr.size}) plot(x, y, xlim = c(1, #{xr.max}), ylim = c(1, #{yr.max})) dev.off() RCOMMANDS
    • 僕が想う理想の言語
      • 学ぶのが難しくない
      • さくっと気持ち良く書けて読みやすい
      • 「生態系」が豊かで育てるコミュニティがいい
      • 「使いたい」と思うキラーアプリがある
    • Ruby on Rails
      • Ruby のキラーアプリ
        • ビジネスをやっている人もこれに反応!
      • Web アプリの自動構築システム
        • プログラムコード/テスト自動生成 (rails)
        • テスト自動実行、 DB 自動ビルド (rake)
        • デプロイ自動実行( capstrano)
    • Ruby on Rails
      • なぜ Ruby ?
        • Ruby : こうしたら、ああ、やっぱりこうなるね」的な感覚
        • Rails :Web ドメインに特化した語彙を追加
        • Ruby 的な直感がはたらくセンスが共通
        • 日本製じゃないけど、日本的な「おもてなしの精神」ではあるまいか