Ruby
PHP
Rails

PHPのアレはRubyで書くとコレ

More than 1 year has passed since last update.

最近、PHPで書かれたコードをRubyに移行している。
(CodeIgniter => Rails)

で、あのコードはどう書くんだろうという奴をつらつらとメモってみる。

※同じ挙動をするという点を今は大事にしているのでRubyらしさは後から。

前提

PHP 5.4 => Ruby 2.0.0

Rails 3.2.x

配列周り

<?php
// 代入
$ids = [];
$ids[] = 1;
$ids[] = 2;
$ids[] = 3;
$ids[] = 4;
$ids[] = 1;

// イテレーション
foreach ($ids as $id) {
  echo "id => {$id}\n";
}

// unique
$ids = array_unique($ids);

# 代入
ids = []
ids << 1
ids << 2
ids << 3
ids << 4
ids << 1

# イテレーション
ids.each do |id|
  puts "#{id}"
end

ids.map {|id| puts "#{id}"}

ids.map(&method(:puts))

# unique
ids.uniq!

ハッシュ

<?php
$items = [
  "key1" => "value1",
  "key2" => "value2",
  "key3" => "value3"
];

// イテレーション
foreach ($items as $key => $value) {
    echo "{$key} => {$value}\n";
}

// イテレーション2
foreach ($items as $value) {
    echo "{$value}\n";
}
# シンボル使ってるから厳密には違う
# 大抵、この後JSONにするから問題にならない
items = {
  key1: "value1",
  key2: "value2",
  key3: "value3"
}

# イテレーション
items.each do |key, value|
  puts "#{key} => #{value}"
end

# イテレーション2
items.each_value do |value|
  puts "#{value}"
end

ループ

<?php
// continue
foreach ($ids as $id) {
    if ($id % 2 == 0) continue;
    echo "id => {$id}\n";
}
# continue
ids.each do |id|
  next if id.even?
  puts "id => #{id}"
end

よくやっている処理

<?php
// idをキーにして配列を初期化しておく
$results = [];
foreach ($ids as $id) {
  $results[$id] = false;
}

// user_idだけ取りたい
$user_ids = [];
foreach ($users as $user) {
    $user_ids[] = $user->id;
}

// user_idだけ取りたい2
$user_ids = array_map(function($v) { return $v->id; }, $users);

// user_idをキーにしたい
$results = [];
foreach ($users as $user) {
    $results[$user->id] = $user;
}
# idをキーにして配列を初期化しておく
results = {} # PHPの頃の癖で[]にしておかしくなる事が何度も…。
ids.each do |id|
  results[id] = false
end

ids.each_with_object({}) {|id, h| h[id] = false }

results = ids.inject({}) {|h, id| h[id] = false; h }

results = {}.tap {|h| ids.map {|id| h[id] = false}}

# user_idだけ取りたい
user_ids = users.map {|user| user.id }
user_ids = users.map(&:id)

# user_idをキーにしたい(ActiveSupport)
results = users.index_by(&:id)