Upload
higaki
View
1.908
Download
0
Embed Size (px)
DESCRIPTION
PHPカンファレンス関西2014
Citation preview
2014年6月28日
PHPerのためのRuby教室
ひがき @ Ruby関西
Rubyとは• まつもとゆきひろ氏が開発• スクリプト言語• オブジェクト指向言語• Ruby on Railsが有名
Rubyの世界観• 文法だけではない違い
– データ構造– イディオム– ライブラリ– 開発環境
• 考え方に影響を与える
Rubyとは• matz が考えた最強のプログラミング言語• 性能よりも生産性• 開発者に心地よい言語
Rubyをキメると気持ちいい
PHPと Ruby
できることに違いはない
Rubyの数値# $age = 49;
age = 49
# $price = 10000;
price = 10_000 # => 10000
# M_PI
Math::PI # => 3.141592653589793
Rubyの整数2 ** 1024 # => 1797693134862315907729305
1907890247336179769789423065727343008115
7732675805500963132708477322407536021120
1138798713933576587897688144166224928474
3063947412437776789342486548527630221960
1246094119453082952085005768838150682342
4628814739131105408272371633505106845862
9823994724593847971630483535632962422413
7216
Rubyの文字列# $name = ’matz’;
name = ’matz’
# "$name($age)";
"#{name}(#{age})" # => "matz(49)"
Rubyの配列# $a = array(1, 2, 3);
a = [1, 2, 3]
a.class # => Array
# $h = array(’a’ => 1, ’b’ => 2);
h = {’a’ => 1, ’b’ => 2}
h.class # => Hash
Rubyの特徴 ブロックa = [1, 2, 3]
a.each do |i|
puts i * i
end
# >> 1
# >> 4
# >> 9
Rubyの特徴 ブロックa = [1, 2, 3]
a.each{|i| puts i * i}
# >> 1
# >> 4
# >> 9
PHPの foreach と何が違うの?• each は Array のメソッド• ブロックは each の引数
– 高階関数
高階関数a = [1, 2, 3]
puts_square = Proc.new do |i|
puts i * i
end
a.each(&puts_square)
# >> 1
# >> 4
# >> 9
ファイル入出力とブロック# $fp = fopen("data.txt", "r");
f = open("data.txt")
while buf = f.gets
# ... なにか ...
end
# fclose($fp);
f.close
ファイル入出力とブロック# file_get_contents("data.txt");
open("data.txt"){|f| f.read}
# file("data.txt");
open("data.txt"){|f| f.readlines}
ファイル入出力とブロックアプリケーション ブロック File
�� ��{|f| f.read}
-生成
-open
� 呼出
�close
×
制御構造ではなくメソッドdef verbose
yield
yield
end
verbose{puts ’こんにちは’}
# >> こんにちは# >> こんにちは
Mix-in• クラスにモジュールを取り込む機能
– モジュール: 実装の集合体• Enumerable
– 繰り返しに関するモジュール– each メソッドを持つクラスで利用可能
BasicObject
Object
4
4
�Mix-in�Kernel
�Mix-in�Enumerable
4
mapselect
inject
Array
Hash
each
each
4
繰り返し Enumerablea = [1, 2, 3, 5]
a.map{|i| i * i} # => [1, 4, 9, 25]
a.select{|i| i.odd?} # => [1, 3, 5]
a.inject{|s, i| s + i} # => 11
a.find{|i| i.odd?} # => 1
a.all?{|i| i.even?} # => false
a.any?{|i| i.even?} # => true
Rubyの特徴 オープンクラス"ruby".class # => String
"ruby".upcase # => "RUBY"
"ruby".compact
# ~> -:4:in ‘<main>’: undefined method
‘compact’ for "ruby":String (NoMethodError)
class String
def compact
gsub(/\r?\n/, ’’)
end
end
s = "No Ruby,
No Life."
s.compact # => "No Ruby,No Life."
自分の足を撃つ自由Rubyは君を信頼する。Rubyは君を分別のあるプログラマとして扱う。Rubyはメタプログラミングのような強力な力を与える。ただし、大いなる力には、大いなる責任が伴なうことを忘れてはいけない。
—メタプログラミングRuby 序文より
Rubyの特徴 DSL
• DSL (Domain Specific Language)
– ドメイン特化言語∗ 高い抽象度
– Rubyは内部DSLを作りやすい
Rubyのクラスclass Person
def initialize name
@name = name
end
end
person = Person.new(’matz’)
person.name
# ~> -:7:in ‘<main>’: undefined method
‘name’ for #<Person:0x007fe8409c8eb8 @name="matz"> (NoMethodError)
設定かプログラムか DSLclass Person
attr_accessor :name
end
person.name # => "matz"
person.name = ’MATZ’
person.name # => "MATZ"
代入もメソッドclass Person
def name
@name
end
def name= name
@name = name
end
end
Object
Module
attr accessor
4
4
Class Person:Class
メソッドを作るメソッドdef self.my_attr_accessor var
instance_eval do
define_method(var) do
instance_variable_get("@#{var}")
end
define_method("#{var}=") do |val|
instance_variable_set("@#{var}", val)
end
end
end
DSLはつくれる• 宣言的に記述する• カッコを使わない
– ( ) メソッドの引数– [ ] 配列– { } ハッシュ、ブロック
Sinatra の例 DSLrequire ’sinatra’
get ’/’ do
"PHP Kansai"
end
カッコを使うと……require(’sinatra’)
get(’/’) {
"PHP Kansai"
}
配列の[ ]を取りたいdef sum(ary)
ary.inject{|s, i| s + i}
end
sum([1, 2, 3, 4, 5]) # => 15
sum [1, 2, 3, 4, 5] # => 15
可変長引数を使うdef sum(*ary)
ary.inject{|s, i| s + i}
end
sum 1, 2, 3, 4, 5 # => 15
ハッシュの{ }を取りたいdef max(hash)
hash.max{|a, b| a.last <=> b.last}
end
max({:AAPL=>566.71,
:GOOG=>605.23, :MSFT=>31.16})
# => [:GOOG, 605.23]
最後の引数なら省略可def max(hash)
hash.max{|a, b| a.last <=> b.last}
end
max :AAPL=>566.71,
:GOOG=>605.23, :MSFT=>31.16
# => [:GOOG, 605.23]
ハッシュの => も取りたいmax :AAPL=>566.71,
:GOOG=>605.23, :MSFT=>31.16
# => [:GOOG, 605.23]
max AAPL: 566.71,
GOOG: 605.23, MSFT: 31.16
# => [:GOOG, 605.23]
DSLを作ってみようclass Page
def layout(name, *size, margin)
...
end
end
カッコを使うと……page.layout(:A4, [210, 297],
{:top => 10,
:bottom => 20,
:left => 18,
:right => 24})
これは Rubyのコードですpage.layout :A4, 210, 297,
top: 10,
bottom: 20,
left: 18,
right: 24
なぜDSL• 抽象度・表現力が高い• 問題領域に集中できる
まとめ• PHPも Rubyも、できることに違いはない• Rubyの特徴
– ブロック– Mix-in
– オープンクラス– DSLを作りやすい
もしRubyに興味を持ったら• コミュニティ
– Ruby関西– Minami.rb
– amagasaki.rb
– Shinosaka.rb
– Kyoto.rb
– Nishiwaki.rb & Higashinada.rb
– Wakayama.rb
Rubyをキメると気持ちいい