Upload
sho-hashimoto
View
14.853
Download
13
Embed Size (px)
DESCRIPTION
Ruby初級入門という勉強会やりました http://shokai.org/blog/archives/7966 http://gyazz.com/masuilab/Ruby初級入門2013
Citation preview
Ruby初級入門@shokai
2013年7月16日(火)
@masuilab
私
•@shokai (しょうかい)
•趣味:料理、glitch
Ruby2.0.0をインストールしよう
なぜMacに入ってるRuby
じゃだめなの?• 1.8.7は開発終了したから
• 最近はライブラリ作ってる人もだいたい2.0用に作ってるから
• 今は過渡期だからちょっと面倒だけどそのうち良くなるはず
• 次のOSXには2.0.0が入ってるという噂
苦行 Ruby2.0.0インストール
• http://gyazz.com/masuilab/MacにRuby2.0.0インストール
• App Store.appからXCodeインストール、XCodeの環境設定からcommand line toolsもインストール
• osx-gcc-installerをインストール
• Homebrewをインストール
• Homebrewでrbenvとruby-buildをインストール
• % brew install rbenv ruby-build readline openssl
苦行 Ruby2.0.0インストール(2)• ruby2.0最新版のpatch levelを確認
• % rbenv install --list | grep 2.0
• 2.0.0-p247がない場合、ruby-buildが古い
• brew updateしてruby-build入れなおす
• Ruby2.0.0をインストール
• % rbenv install 2.0.0-p247
• % rbenv global 2.0.0-p247
• % gem install bundler rake rbenv-rehash
• % rbenv rehash
• これでruby2.0.0-p247が使えるようになっているはず
苦行 Ruby2.0.0インストール(3)
• Rubygems, SSL, Digest, SHA1, md5などで不具合が出る
• 解決方法はだいたいここに書いてある
• http://shokai.org/blog/archives/7832
• http://shokai.org/blog/archives/7497
• ruby1.9.2-p320をビルドして、digest関係をコピーしてくる簡単な苦行です
UbuntuにRuby2.0.0インストール• MacのようなSSL, Digest, Rubygemsの不具合が無いので楽です
• 必要なもの入れる
• % sudo apt-get install build-essential libreadline-dev libssl-dev
• rbenv, ruby-buildをgithubから入れる(aptのは古い)
• % git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
• % mkdir ~/.rbenv/plugins
• % git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
• % rbenv install 2.0.0-p247
以下Ruby2.0.0
インストール中のお話
Rubyに向いてること• テキスト処理、正規表現、配列やHashの複雑なデータ構造、関数型プログラミング
• HTTP、HTMLやXMLみたいなのの解析、並列実行、イベント駆動、webサービス
• 言語ルールの改変(メタプログラミングなど)
• 絶対にかっこよく書ける
• こんなメソッドがあったらいいのに、が絶対ある
色々できる• Mac用のツールを作れる。Platypusを使う
• gemで配布できる
• Macなどにインストールするサービスも作れる
• launch-agentやforemanなどのgemを使う
• 自分のマシン内にHTTPサーバーを立てるアプリ
• ワンライナー、他のUNIXツールとpipeで連携、CUIツール
• ArduinoやPhidgetsなどで実世界コンピューティング
色々な所で動く
• VPS
• 組み込みボードのLinux
• 自分のMac
• 仮想マシンのLinux
実行のしかた• % ruby ファイル名
• 拡張子は.rb
• 定期的に実行
• crontabを使おう
• クローラやbotなど
• 常に実行
• foremanで各OSにサービスとしてインストールしよう
• OS起動時に自動起動、エラーで落ちても再起動する
Platypus
• スクリプト言語をMac用アプリにしてくれるラッパー
• Gyazo(Mac用クライアント)
• clip2htmlescape
• など
RailsとSinatra
• よく何が違うのか聞かれる
• ぜんぜん違うよ
• Railsやめとけ
Railsやめとけ• Railに乗れないことが多い
• レールに乗ったアプリは簡単に作れる
• SNSやECみたいなサイト。静的ページとDBがたくさんあってログインしたりカートに入れたり友だち申請するようなやつ
• ユーザインタフェースやおもしろアプリの研究は、ほぼ確実にレールを外れる
Sinatra
• 超シンプル
• このURLにアクセスきたら→(何かしてから)→これを返す
• HTTP通信の薄いラッパー
• にcookieやsessionなどの便利ツールをちょっと足した感じ
• RocketIOがある
• 実験的なことに使いやすい
Rubygems
• gemコマンドでインストールできる便利ライブラリ集
• 59480種ある
• % gem install 名前
• http://rubygems.org/gems/名前 にドキュメントがある
• そこからGitHubに飛べる
gemの使い方を調べる• READMEを読む
• サンプルを見る
• sampleかexampleみたいなディレクトリがあるはず
• testを読む
• testかspecというディレクトリがあるはず
• ソースを読む
• 手元にgit cloneしてから git grep -C10 キーワード
gemの使い方を調べる(2)
• pryの ls と $ を使うと、関数の定義が見れる
• (次のページヘ)
コードが引数も中身も全部みえる
$ メソッド名
Tw::Clientの使い方を調べる
gemの使い方を調べる(3)• awesome_print で対象の#methodsを見る
• 引数も全部見えるObjectインスタンスで引き算すると綺麗になる
どんなgemを使っているか• http://shokai.org/blog/archives/7931
% find $HOME -name Gemfile | grep "^$HOME/.*Gemfile$" | xargs grep "^gem " | ruby -lane 'puts $_.scan(%r{["'\\\'']([^"'\\\'']+)["'\\\'']})[0]' | sort | uniq -c | sort -nr
% find $HOME -name "*.r[bu]" | grep "^$HOME/.*\.r[bu]$" | xargs grep "^ *require " | ruby -lane 'puts $_.scan(%r{["'\\\'']([^"'\\\'']+)["'\\\'']})[0]' | sort | uniq -c | sort -nr
Macbook Air内のGemfileから集計
Macbook Air内の.rbと.ruから集計
便利なgem• addressable
• 日本語が含まれたURIなどを扱う
• arduino_firmata, phidgets-ffi
• ArduinoやPhidgetsを操作
• args_parser
• CUIアプリの引数をparse
• asearch, levenshtein
• 文字列間の類似度を判定
便利なgem(2)• backports
• Ruby1.9以降の関数を1.8で使えるようにする
• capybara, capybara-webkit
• Ruby内でqtでwebkitが使える
• data_mapper, dm-mysql-adapter, dm-sqlite-adapter
• SQLその他の汎用ORマッパー
• diff-lcs
• 2つの文字列の差分を取る
便利なgem(3)• event_emitter
• 全てのmodule/class/instanceにイベント機能を追加
• eventmachine
• イベント駆動フレームワーク
• feed-normalizer
• RSSやAtomなどなんでも同じように扱える
• foreman, launch-agent
• プロセス管理ツール、OSにインストール
便利なgem(4)• growl, g
• growlする
• haml, sass, coffee-script
• HTML, CSS, JSのメタ言語
• hashie
• HashやArrayを使いやすくする
• headless
• xvfb (Xの仮想フレームバッファ)を作る
便利なgem(5)• httparty
• HTTPのラッパー。綺麗に書ける
• hugeurl
• 短縮URLを展開
• json
• JSONをパース・シリアライズ
• logger
• ログレベルごとに出力
便利なgem(6)• mecab, igo-ruby
• 形態素解析、分かち書き
• mechanize
• webブラウザのふりをしてHTTPアクセス
• mini_exiftool
• 写真や動画のexif情報を読む
• minitest
• シンプルなテストツール
便利なgem(7)• nokogiri
• HTML, XMLのparse
• oauth
• oAuthで認証
• octokit
• GitHub API
• parallel
• for文を並列実行
便利なgem(8)• pit
• 設定やパスワードをホームディレクトリに保存
• rack
• WAFとWebサーバーの接続部分
• rainbow
• 色がつく puts “hello”.color(:green)
• rake
• Rubyでmakeが書ける
便利なgem(9)• rbenv-rehash
• 自動的にrbenv rehashしてくれる
• rmagick, mini_magick
• imagemagickのラッパー
• serialport
• シリアルポートを使う
• sinatra-contrib
• Sinatraの便利ライブラリまとめ
便利なgem(10)• sinatra-rocketio
• Sinatraでwebsocket/cometが美しく使える
• skype, im-kayac
• メッセンジャーを使う
• stringio
• IOとバイナリでやりとりする
• thin, mongrel, webrick, rainbows, unicorn
• Rack対応webサーバー
便利なgem(11)• tiqav
• ネタ画像検索ナンバーワン
• tmp_cache
• memcache風に揮発するオンメモリキャッシュ
• tw, twitter, userstream
• twitterのライブラリ
• weather_jp, weather-report
• MSNとLivedoorから天気取得
便利なgem(12)
• awesome_print
• ppより見やすいprint。とくにHashやmethodsが見やすい
• pry
• irbのすごい版。$ 関数名 で関数が定義されているコードが見れる。gemの使い方を調べるのに便利
@shigeyas先生より
gemを作る• gemを作ることでRubyを理解できるようになる
• たいして難しくないし、審査も無い
• 次の機会があればgemの作り方やりましょうか
bundler
• 将来gemをたくさん使うようになったらbundlerのことを思い出してください
• 使わないとお前のアプリは1年以内に死ぬ!!マジで!!
• Ruby書くならBundler使えhttp://shokai.org/blog/archives/7262
Rubyにどこから手を付けるか• はじめ:ググりながら簡単なアプリを作る
• インターネットからデータを取得して自分に送るようなやつから始めるといいのでは
• SkypeやGTalkやTwitterで自分に通知するようなの
• 作ったツールは毎日愛用して、不満がある所を直そう
• 本は読まないでいい
• Rubyは超間違った情報はWebに無いから安心していい
• 次:人の作ったものを見る
オブジェクト指向
• class作って継承してnewして~みたいな考え、とりあえず捨てよう
• それはクラス指向です
• たぶんあなたのやりたい事は(最初は)メソッドベタ書きかクラスメソッドで実現できる
• 他の言語(Javaとか)でクラスを書かなければ出来なかった事も、Rubyなら配列やHashだけでできると思うよ
プログラムの基礎
puts, print, p
puts "hello work"
main.rb
% ruby main.rb
実行
条件式a = 3if a > 2 puts "大きい"else puts "小さい"end
puts "大きい" if a > 2
後ろにも付けれる
ifの否定形のunlessもある
条件式(2)
num = 3case numwhen 1 puts "1です"when 2 puts "2です"when 3 puts "3です"else puts "その他"end
case when - C言語のswitch文みたいなもの
関数def square(num) num * numend
puts square(2)puts square 3
def 名前 ~ end
かっこ付けても付けなくても良いreturn書いても書かなくても良い
関数(2)
def send_mail(to, from="[email protected]") ## (略)end
send_mail "[email protected]"send_mail "[email protected]", "[email protected]"
引数のデフォルト値を指定できる
繰り返しi = 0loop do puts i += 1 break if i > 10end
i = 0while i < 10 puts i += 1end
i = 010.times do puts i += 1end
1.upto(10) do |i| puts iend
while, loop, times, upto, downto
Array
arr = [1,3,5,2,4,1,2,3]p arrp arr.reverse
arr.each do |i| puts iend
arr.uniq.sort.each do |i| puts iend
arr.select{|i| i % 2 == 0 }.each do |i| puts iend
each, map, find, flatten, grep, sort, uniq, select, reject, delete_if, reverse, min, max
Hash
h = { :name => "shokai", :mail => "[email protected]", :web => "http://shokai.org"}
p hp h.keysp h.values
h.each do |k,v| puts "#{k} : #{v}"end
each, map, keys, values, find, grep, select, reject,
正規表現str = "今日はかずすけにいこう"
p str =~ /あああ/ # => nilp str =~ /かずすけ/ # => 3
p str.gsub(/すけ/, "どん") # 置換p str.split(/は/) # 分割p str.scan(/は(.+)にいこう/)[0] # 抜き出し
gsub, split, scan
module
module Foo BAR = "const value"
def self.baz "module method" endend
puts Foo::BARputs Foo.baz
ただの入れ物、入れ子にできる
classclass User attr_accessor :name, :age
def initialize(name, age) @name = name @age = age end
def to_s "#{@name}さん #{@age}さい" endend
user = User.new "shokai", 28puts user.nameputs user
user.name = "ABCD"puts user
@付きはインスタンス変数
class(2)class User def initialize(name, age) @name = name @age = age end
def to_s "#{@name}さん #{@age}さい" end
def age=(age) ## setter raise ArgumentError, "年齢がおかしいです" if age.class != Fixnum @age = age end
def age ## getter @age endend
末尾に=が付いた関数はsetterになる
Error
test.rb:15:in `age=': 年齢がおかしいです (ArgumentError) from test.rb:27:in `<main>'
どのファイルの何行目にエラーが出たかわかる
巨大なError
/Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/backports-3.3.3/lib/backports/tools.rb:328:in `require': /Users/sho/projects/rocketio/rocketio-tiqav-chat/main.rb:12: syntax error, unexpected keyword_end, expecting end-of-input (SyntaxError) from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/backports-3.3.3/lib/backports/tools.rb:328:in `require_with_backports' from /Users/sho/projects/rocketio/rocketio-tiqav-chat/config.ru:15:in `block in <main>' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:55:in `instance_eval' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:55:in `initialize' from /Users/sho/projects/rocketio/rocketio-tiqav-chat/config.ru:in `new' from /Users/sho/projects/rocketio/rocketio-tiqav-chat/config.ru:in `<main>' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:49:in `eval' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:49:in `new_from_string' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:40:in `parse_file' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/server.rb:277:in `build_app_and_options_from_config' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/server.rb:199:in `app' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/server.rb:314:in `wrapped_app' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/server.rb:250:in `start' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/server.rb:141:in `start' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/bin/rackup:4:in `<top (required)>' from /Users/sho/.rbenv/versions/2.0.0-p247/bin/rackup:23:in `load' from /Users/sho/.rbenv/versions/2.0.0-p247/bin/rackup:23:in `<main>'
おわかりいただけるだろうか
巨大なError
/Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/backports-3.3.3/lib/backports/tools.rb:328:in `require': /Users/sho/projects/rocketio/rocketio-tiqav-chat/main.rb:12: syntax error, unexpected keyword_end, expecting end-of-input (SyntaxError) from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/backports-3.3.3/lib/backports/tools.rb:328:in `require_with_backports' from /Users/sho/projects/rocketio/rocketio-tiqav-chat/config.ru:15:in `block in <main>' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:55:in `instance_eval' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:55:in `initialize' from /Users/sho/projects/rocketio/rocketio-tiqav-chat/config.ru:in `new' from /Users/sho/projects/rocketio/rocketio-tiqav-chat/config.ru:in `<main>' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:49:in `eval' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:49:in `new_from_string' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/builder.rb:40:in `parse_file' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/server.rb:277:in `build_app_and_options_from_config' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/server.rb:199:in `app' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/server.rb:314:in `wrapped_app' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/server.rb:250:in `start' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/lib/rack/server.rb:141:in `start' from /Users/sho/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rack-1.5.2/bin/rackup:4:in `<top (required)>' from /Users/sho/.rbenv/versions/2.0.0-p247/bin/rackup:23:in `load' from /Users/sho/.rbenv/versions/2.0.0-p247/bin/rackup:23:in `<main>'
正直どこから読めばいいかわからないけど、自分のアプリ内の .rb ファイルの名前を探そう
ココ
IO
File.open("hoge.txt", "w+") do |f| f.write "abcdefg"end
File.open("hoge.txt") do |f| f.readlines.each do |line| ## 行ごとに読む puts line endend
ファイルの読み書き
IO(2)
cat hoge.txt | ruby main.rb
UNIX PIPE入力
while line = STDIN.gets puts lineend
ARGF.each do |line| puts lineend
main.rb
どこから手を付ければいいか
とりあえず日常的に使うツールを作るのがいいのでは?• ぶっこぬき系がいいのでは?
• ぶっこぬき == クロール・HTML解析・DBに貯めて・通知するという総合芸術
• pi○ivをクロールしてRSSを出すとか
• SkypeやTwitterで自分に通知するとか
かっこいい書き方ができる
• 先にsample.rbを書く
• マジかよと思うようなサンプルコードを書く
• Rubyなら、それを実行できるライブラリは必ず作れる
chat = Skype.chats.find{|c| c.title =~ /増井研/ }chat.messages.each do |m| puts "#{m.user} #{m.body}"endchat.post "おなかすいた"
実演:ぶっこぬき