はじめに
- この記事は
Ruby
の書き方・読み方を最低限説明するために作成されたものである。 -
PHP
がある程度普通に触れている人向けに、Ruby
ではどう書く?みたいなところが中心 -
Ruby
の環境は既に整ってる前提
基本思想
PHP
は関数が基本
- 例えばある配列から先頭の要素を取り出す時
$a = array(1,2,3);
$first = array_shift($a);
var_dump($first);
var_dump($a);
-
array_shift
という関数に引数を渡すことで任意の処理を行う。
Ruby
はオブジェクトが基本
- 同様に配列から先頭の要素を取り出す時
a = [1,2,3]
first = a.shift
p first
p a
Array
オブジェクトa
のshift
メソッドで先頭の要素を取り出す。
これがPHP
とRuby
の基本思想の違いである。
まず先に出力方法
- 基本的な出力形式を押さえておく。
-
PHP
でいう「困ったらダンプしてみる」というのはRuby
でも通用するのでp
メソッドを覚えておくと何かと便利。 - コメント文は
#
PHP | Ruby |
---|---|
echo('hoge'); | print 'hoge' |
echo("hoge¥n"); | puts 'hoge' |
var_dump('hoge'); | p 'hoge' |
//コメント文 | #コメント文 |
実際に出力してみよう
コンソールでirb
と打つとインタラクティブシェルが起動する。まずはファイルを作成せずにシェルで挙動を確認しましょう。
PHP | Ruby |
---|---|
php -a | irb |
演習問題1
インタラクティブシェルでprint
, puts
, p
の出力を試してみましょう。
拡張子と実行方法
プログラムファイルの拡張子は.rb
、実行はruby
コマンド
PHP | Ruby |
---|---|
.php | .rb |
php hoge.php | ruby hoge.rb |
<?php
$a = 'hoge';
var_dump($a);
a = 'hoge'
p a
-
<?php
等の開始タブが不要 - 変数に
$
不要 - 行末にセミコロン不要(つけても良い)
- カッコの省略可(つけても良い)
演習問題2
実際に上記ファイルを作って実行してみましょう。
ループ
<?php
for($i=0; $i<10; $i++){
echo($i."\n");
}
for i in 0...10 do
p i
end
ここで覚えて欲しいのは0...10
の範囲オブジェクト
0..10
だと10を含む、0...10
だと10を含まない。
またPHP
で中括弧で囲んでいる部分はそのままRuby
ではdo ~ end
で置き換えることができる。
ちなみに上記のfor
文はほぼ使わない。
私も久しぶりに使うにあたってドキュメントを参照しながらでないと書けなかった(汗
上記の例でいうと範囲オブジェクトに対してeach
メソッドを使って
(0...10).each do |i|
p i
end
こんな感じに書くのが自然である。
もっと言うと基本は配列等のオブジェクトに対してループを回すことが大半である(PHP
でいうところのforeach
と同義)
そのあたりは次の配列の項で触れる。
演習問題3
1から100までの偶数を出力して下さい。
配列
<?php
$a = array('Hello', 'new', 'world');
foreach($a as $value){
var_dump($value);
}
a = ['Hello', 'new', 'world']
a.each do |value|
p value
end
これが前項で述べていたオブジェクト(この場合には配列)に対してeach
でループを回している様子である。foreach
だと思えば馴染みやすいかと思う。
Array
オブジェクトに色々なメソッドがあるので適宜使って欲しい。
PHP | Ruby |
---|---|
sort($a) | a.sort |
empty($a) | a.empty? |
array_unique($a) | a.uniq |
count($a) | a.count |
ここで出てきたのでついでに紹介するがRuby
ではメソッド名に!
と?
が使用できる。
自由に命名に使って良いが慣習として
-
true
orfalse
のboolean
を返すメソッドには末尾に?
- 対象のオブジェクトに対して破壊的なメソッドには末尾に
!
を使う。
例えばarray.uniq
はarray.uniq!
という元の配列を上書き(破壊)してしまうものも存在する。
演習問題4
次の処理のPHP
をRuby
に書き換えてみましょう。
<?php
// カンマ区切りの文字列を配列に格納
$string = 'Hello, new, world';
$array = explode(', ', $string);
print_r($array);
// 配列の各要素をカンマ区切りの文字列に変換
$convert_string = implode(', ', $array);
print_r($convert_string);
// カンマ区切りの文字列をコロン区切りの文字列にする
print_r(str_replace(',', ':', $convert_string));
条件分岐
<?php
$a = 'hoge';
if($a === 'hoge'){
echo("true\n");
}
a = 'hoge'
if a == 'hoge'
p 'true'
end
特に難しいことはない。
- カッコの省略
- 中括弧が
then ~ end
(then
は省略可) -
==
でPHP
の===
と同じく厳密比較
Ruby
ならではの書き方を以下に記載する。
unless
<?php
$a = 'hoge';
if($a !== 'moge'){
echo('true');
}
a = 'hoge'
unless a == 'moge'
p 'true'
end
unless
とは簡単に言えば!==
と同義である。
簡単に否定の比較ができるので割と重宝する。
!
よりも見落としにくい。
elsif
<?php
$a = 'hoge';
if($a === 'moge'){
echo('moge');
} else if($a === 'hoge'){
echo('hoge');
} else{
echo('else');
}
a = 'hoge'
if a == 'moge'
p 'moge'
elsif a == 'hoge'
p 'hoge'
else
p 'else'
end
else if
でもelseif
でもなくelsif
なので注意
後置if
a = 'hoge'
p 'true' if a == 'hoge'
p 'true' unless a == 'moge'
個人的にRuby
が好きな理由の1つ
条件式を後ろに配置できる。
ものによっては1行でまとまって非常にスッキリするのでオススメ
英語の文法としても自然(と思う)
PHP
にはないのでPHP
版は割愛
演習問題5
1から30の間でFizzBuzz
をRuby
で実装してみましょう。
※ FizzBuzz
とは3の倍数でFizz
, 5の倍数でBuzz
, 15の倍数でFizzBuzz
, それ以外の時は数値を出すプログラム問題のことである。
ハッシュ(連想配列)
<?php
$a = array('key1' => 'value1', 'key2' => 'value2');
print_r($a);
foreach($a as $key => $value){
echo("$key, $value\n");
}
echo($a['key2']."\n");
a = {'key1' => 'value1', 'key2' => 'value2'}
p a
a.each do |key, value|
puts key + ', ' + value
end
puts a['key2']
ハッシュとは簡単に言うとPHP
でいうところの連想配列である。
キーとそれに対応する値を保持する形
これも連想配列を理解していれば特に難しいことはない。
リテラルが中括弧を使用する点に注意
演習問題6
'key1' => 1
この形で10まであるハッシュをループで生成して下さい。
生成したハッシュに対して、値が5以上であるもののkey値を出力して下さい。
Hint: キャスト
PHP | Ruby |
---|---|
(int)'5' | '5'.to_i |
(string)5 | 5.to_s |
関数
<?php
function add($a, $b){
$sum = $a + $b;
return $sum;
}
$result = add(1, 2);
var_dump($result);
def add(a, b)
sum = a + b
return sum
end
sum = add(1, 2)
puts sum
PHP
のfunction
をdef
に置き換えればほぼそのまま流用できる。
ただRuby
では上記のような書き方は普通しない。
通常は以下のような書き方になる。
def add a, b
a + b
end
puts add(1, 2)
Ruby
ではreturn
を省略することができる。
省略した場合は関数内で最後に評価された値が自動で返る(この場合はa+b
の結果)
ここはRuby
のソースを読む上で勘違いしやすいところなので注意。
演習問題7
引数: array
戻値: hash
配列を渡したらその中に入っている数値を全て足した結果を返す関数を作成して下さい。
配列の中が全て整数でなければ加算できないのでsuccess
にfalseを入れて返して下さい。
例:
[1,2,3,4,5,6,7,8,9,10] >> {'success' => true, 'value' => 55}
[1,2,3,'a',5,6,'b',8,9,10] >> {'success' => false, 'value' => nil}
Hint: nil
nil
とはPHP
でいうところのNULL
と同義である。
PHP | Ruby |
---|---|
NULL | nil |
is_null(NULL) | nil.nil? |
例外処理
<?php
try {
$a = 'moge';
if($a === 'hoge'){
echo("hoge\n");
} else {
throw new Exception('exception occur');
}
echo('finish');
} catch(Exception $e){
var_dump($e->getMessage());
}
begin
a = 'moge'
if a == 'hoge'
puts a
else
raise 'exception occur'
end
rescue => message
puts message
end
PHP
のtry-catch
はRuby
ではbegin-rescue-end
に置き換わる。
また、例外を発生させる方法はthrow
をraise
に置き換える。
クラス
<?php
class ParentClass
{
public function sayHello(){
echo("Hello!\n");
}
}
class ChildClass extends ParentClass
{
}
$a = new ParentClass();
$a->sayHello();
$b = new ChildClass();
$b->sayHello();
class ParentClass
public
def sayHello
puts 'Hello'
end
end
class ChildClass < ParentClass
end
a = ParentClass.new
a.sayHello
b = ChildClass.new
b.sayHello
簡単に違いを表す
PHP | Ruby |
---|---|
extends | < |
new Class | Class.new |
$a->hoge() | a.hoge |
また、PHP
ではメソッド1つ1つにpublic
, protected
, private
をつけるのに対し、Ruby
では宣言箇所以下ではそのアクセス権に絞られる。
以下の例で言うとa,b,c
がpublic
, d,e
がprotected
, f
がprivate
となる。
class hoge
public
a
b
c
protected
d
e
private
f
end
演習問題8
上記の例にChildClass
を継承したGrandChildClass
を追加して下さい。
GrandChildClass
ではsayHello
メソッドに引数で文字列を渡すとその人に対してHelloするようにメソッドを拡張して下さい。
例: c.sayHello('yamamoto') >> 'Hello! yamamoto!'
ブロック
ブロックに関してはPHP
に置き換えるのが難しいため割愛
こちらの記事が大変参考になるので気になる人はこちら
おわりに
これでRuby
の基本的な書き方は押さえられました。
次回はRails
にスポットを当てる予定です。
Appendix
演習問題の解答例を載せておきます。
解き方は1通りではないし私の解答がイケてない可能性もあるのであくまで例ということで。
演習問題3の解答例
(1..50).each do |i|
p i * 2
end
# 条件文を使った方法はこっち
#(1..100).each do |i|
# p i if i % 2 == 0
#end
演習問題4の解答例
string = 'Hello, new, world'
array = string.split(', ')
p array
convert_string = array.join(', ');
p convert_string
p convert_string.gsub(',', ':');
演習問題5の解答例
(1..30).each do |i|
print 'Fizz' if i%3 == 0
print 'Buzz' if i%5 == 0
print i unless (i%3 == 0 || i%5 == 0)
puts
end
演習問題6の解答例
a = {}
1.upto 10 do |i|
a['key'+i.to_s] = i
end
p a
a.each do |key, value|
p key if value >= 5
end
演習問題7の解答例
def add_all target_array
# 全て数値かチェック
success = number_check(target_array)
result_hash = {'success' => success}
if success
result_hash['value'] = target_array.inject { |sum, n| sum + n }
else
result_hash['value'] = nil
end
result_hash
end
def number_check target_array
target_array.each do |i|
return false unless i.kind_of?(Numeric)
end
true
end
target_array = [1,2,3,4,5,6,7,8,9,10]
p add_all(target_array)
target_array = [1,2,3,'a',5,6,'b',8,9,10]
p add_all(target_array)
演習問題8の解答例
class ParentClass
public
def sayHello
puts 'Hello'
end
end
class ChildClass < ParentClass
end
class GrandChildClass < ChildClass
public
def sayHello(name)
puts 'Hello! ' + name + '!'
end
end
a = ParentClass.new
a.sayHello
b = ChildClass.new
b.sayHello
c = GrandChildClass.new
c.sayHello('yamamoto')