Rubyist九州ruby入門勉強会

1,907 views

Published on

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,907
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Rubyist九州ruby入門勉強会

  1. 1. Ruby 入門勉強会 ( Ruby の を る魅力 知 ) Rubyist 九州 山崎重一郎
  2. 2. オープンソース 世の中にあるものが気に入らなかったら 自分でもっといいものを作ってしまえばいい Ruby の作者 → まつもとゆきひろ氏 ただ、開発にあたって大事にしてきたことはあります。それは、自分が欲しいも のを作ること。僕は短気で(笑)。だから、自分がイライラしないものを作りた かった。シンプルで、わかりやすいもの。誰に気に入ってもらおうとか、使って もらおうとか、そういうものではない。自分が使いたいもの。誰かのために役立 つという利他的精神は、ないわけではないけれど、自分ではあまり意識してない ですね。それよりも、圧倒的に自分がイライラしなくてすむという利己的精神の ほうが強い(笑)。
  3. 3. オープンソース   Ruby = まつもとさんにとっての理想の言語 自分がほしい理想の車、 自分がほしい理想の携帯端末 自分がほしい理想のクラウド、 ... ナショナリズム的な意味ではなく、やっぱり日本人のエンジ ニアが自然にほしがる言語処理系という感じ 「クールジャパン」なんて政府が音頭とると「逆宣伝やめて」 とおもうけど、世界中の人が率直にクールと感じる日本製の 感覚と共通点があるとおもう
  4. 4. 理想の言語って? 用途によって違う 使う人のバックグラウンドや価値観によって違う 時代によって変化する 理想の車?
  5. 5. 僕が想う理想の言語 学ぶのが難しくない さくっと気持ち良く書けて読みやすい 「生態系」が豊かで育てるコミュニティがいい 「使いたい」と思うキラーアプリがある
  6. 6. 僕が想う理想の言語 学ぶのが難しくない さくっと気持ち良く書けて読みやすい 「生態系」が豊かで育てるコミュニティがいい 「使いたい」と思うキラーアプリがある
  7. 7. 学ぶのが難しくない 手続き型言語 手続きで処理を書いていく(わかりやすい) オブジェクト指向言語 大規模開発や仕様を洗練させるのにむいている (最初はわかりにくいけど、慣れれば便利) 関数型言語 分散処理や仕様のテストに適している (関数脳になるまでちょっとたいへん。でも今後は必須?) Ruby は何型言語か?  手続き型、オブジェクト指向、関数型、どれも OK
  8. 8. ちょっと動かしてみる サンプルデータ (people.csv) Twitter のランダムに選択した 28830 人のユーザ情報 フォロワーのフォロワーをランダムに 4 人ずつ 8 ホップ csv 形式にしている id,name,screen_name,time_zone,location,favourites_count,followers_count,friends_coun 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,PacificTime(US &Canada),Vancouver; BC,22,17982,18338, 126901360,mituhiro,mitti2525,nil, 福岡市 ,577,1947,2086,1295 91584317,Yoichi Kato,DRI VI NG_MAUL,Tokyo, 中目黒 or東急田園都市線沿線 ,5,203,159,752 19314650,Chuck Palahniuk,chuckpalahniuk,PacificTime(US &Canada),LosAngeles,1,257790,22,826
  9. 9. 手続き型言語としての 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]
  10. 10. 手続き型言語としての 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], ...
  11. 11. オブジェクト指向言語としての Ruby かなりきっちりしたオブジェクト指向言語 (「オブジェクト指向とは」の話はしません) Ruby のオブジェクトは強く型づけされている 変数には型がなく、宣言なしで使える たくさんの組み込みクラスがある クラス構成はフラットでライブラリはコンパクト クラスは必ずしも作らなくてもいい オブジェクトに直接メソッドを定義することもできる
  12. 12. オブジェクト指向言語としての 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
  13. 13. オブジェクト指向言語としての 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_exec, :__send__] > csv.instance_variables #csv オブジェクトのインスタンス変数 => [:@csv, :@keys] > csv.object_id #csv オブジェクトのオブ ジェクト ID
  14. 14. オブジェクト指向言語としての Ruby > csv.histgram('time_zone') # タイムゾーンごとの頻度の集計 => [["Tokyo", 13464], ["nil", 3317], ["Hawaii", 2690], ["Osaka", 1729], ...] > csv.histgram('followers_count')# フォロワー数ごとの頻度の集計 => [["6", 127], ["5", 126], ["4", 125], ["9", 123], ["2", 122], ["7", 120], ["3", 118], ["12", 117], ["1", 116], ["14", 116], ["11", 115], ["17", 106], ["15", 105], ["22", 102], ["18", 102], ["21", 101], ... ]
  15. 15. オブジェクト指向言語としての 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
  16. 16. オブジェクト指向言語としての 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=" 課長 ">, #<Shain:0x000001009ac418 @post=" 平社員 ">, #<Shain:0x000001009a6e20 @post=" 平社員 ">, #<Shain:0x000001009a1748 @post=" 社長 ">] > list.sort => [#<Shain:0x000001009a6e20 @post=" 平社員 ">, #<Shain:0x000001009ac418 @post=" 平社 員 ">, #<Shain:0x000001009bcb78 @post=" 課長 ">, #<Shain:0x000001009a1748 @post=" 社 長 ">]
  17. 17. 関数型言語としての Ruby 1.9 になって関数型のにおいがちょっと強くなった 関数型言語とは 「関数」とは入力と出力の対の集合=グラフと考える これは処理や手続きではないと思考する脳が必要 変数には副作用がない(代入は一度きり) 時間の概念がない(評価を遅延させたりできる) 関数自体もデータと同列に扱える Ruby の場合 ブロックは関数じゃなくて手続きだけど、 Proc オブジェク トというのに変換すると関数(オブジェクト)になる
  18. 18. 関数言語としての 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)>
  19. 19. ラムダ?  数学の関数の式の定数と変数の違いってなに?      ax + b 先生:「 a と b は定数で x は変数じゃ」(なん で?) 「これが変数」ってはっきりさせるために λ (ラム ダ)を付ける x (ax + b)λ ( xを束縛変数と a,b を自由変数と呼びます)
  20. 20. ギリシャ文字恐怖症 数学の実際の難しさ以上にギリシャ文字が怖い λ (ラムダ)とか、 lambda ( b を忘れそう〜) でも大丈夫! Ruby1.9 では、 -> で lambda を表せるようになった        lambda {|x| 2 x + 3}* は        -> x {2 x + 3}*     とかける 僕は「この -> x は束縛変数だぜ!」と感じている
  21. 21. 関数言語としての 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
  22. 22. 関数言語としての 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
  23. 23. 関数言語としての 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
  24. 24. 関数言語としての 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
  25. 25. 関数言語としての 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}
  26. 26. 関数言語としての Ruby 関数は時間を超越している 遅延評価( Lazy evaluation )ができる言語が多い Ruby には遅延評価機構はないが、似たようなことはやろう と思えばできる > csv = -> { CSV.new('people.csv')} > ... # なんかいろいろ処理をするけどファイルアクセスはまだしない > data = csv.call
  27. 27. 僕が想う理想の言語 学ぶのが難しくない さくっと気持ち良く書けて読みやすい 「生態系」が豊かで育てるコミュニティがいい 「使いたい」と思うキラーアプリがある
  28. 28. さくっと気持ち良く書けて読み やすい こうしたら、こうなる。うんうん。 こうしたら? あー、やっぱりこうなった! > 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]
  29. 29. さくっと気持ち良く書けて読み やすい 文字列の処理 > t = ' さくっと ' + 'cool!' => " さくっと cool!" > t[0] => " さ " > t[2..7] => " っと cool" > line = "85259796,DEVO,DEVO,Pacific Time (US & Canada),United States,0,16237,372,272" > line.split(',') => ["85259796", "DEVO", "DEVO", "Pacific Time (US & Canada)", "United States", "0", "16237", "372", "272n"] > lines = File.readlines('people.csv') > csv = lines.map {|line| line.chomp.split(',')}
  30. 30. さくっと気持ち良く書けて読み やすい あ、なるほどね 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) => " 小学生 "
  31. 31. 僕が想う理想の言語 学ぶのが難しくない さくっと気持ち良く書けて読みやすい 「生態系」が豊かで育てるコミュニティがいい 「使いたい」と思うキラーアプリがある
  32. 32. 「生態系」が豊かで育てるコ ミュニティがいい 土地の値段 交通の利便性、周囲の環境、商業地に近い、 ...  → 生態 系 プログラムの価値 顧客へのアピール度、開発コミュニティ、関連システム、 ライブラリ、技術情報入手の容易さ、生産性、性能 利用者の人口普及率、教育、普及広報活動 Ruby の生態系、コミュニティ 言語処理系としてはかなりいい方、特に日本 Ruby on Rails で生産性が注目され、アピール度が高まった Rubyist 九州も普及にはちょっと貢献している?
  33. 33. 「生態系」が豊かで育てるコ ミュニティがいい ライブラリの利用方法 組み込みライブラリが豊富にある rubygems というツールを使ってネットから
  34. 34. 「生態系」が豊かで育てるコ ミュニティがいい ライブラリの利用方法  (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]]
  35. 35. 「生態系」が豊かで育てるコ ミュニティがいい Ruby は処理速度は速くない 数値計算などの速度重視の処理には適していない C 言語で書かれたプログラムは容易に Ruby から利用でき る JRuby を使うと Java とも連携 R 言語などとも連携可能 様々な DB と接続できる
  36. 36. 「生態系」が豊かで育てるコ ミュニティがいい 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
  37. 37. 「生態系」が豊かで育てるコ ミュニティがいい R 言語を利用する場合 ■ 例 require 'rubygems' require 'rsruby' r = RSRuby::instance xr=[ 1..1000]* yr = xr.map {|a| a 2}** g=r.eval_R(<<-RCOMMANDS) pdf("graph.pdf") 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
  38. 38. 僕が想う理想の言語 学ぶのが難しくない さくっと気持ち良く書けて読みやすい 「生態系」が豊かで育てるコミュニティがいい 「使いたい」と思うキラーアプリがある
  39. 39. Ruby on Rails Ruby のキラーアプリ ビジネスをやっている人もこれに反応! Web アプリの自動構築システム プログラムコード/テスト自動生成 (rails) テスト自動実行、 DB 自動ビルド (rake) デプロイ自動実行( capstrano)
  40. 40. Ruby on Rails なぜ Ruby ? Ruby : こうしたら、ああ、やっぱりこうなるね」的な感覚 Rails :Web ドメインに特化した語彙を追加 Ruby 的な直感がはたらくセンスが共通 日本製じゃないけど、日本的な「おもてなしの精神」ではある まいか

×