kdoc - Ruby

  • 作成日:2014-05-22 10:23:46
  • 修正日:2016-05-09 15:48:59

saveとsave!

↑ページトップへ

saveは失敗時にfalseを返す。

@hoge = Hoge.new(:name => "piyo")
if @hoge.save
  p "ゆっくりしていってね!"
else
  p "ぬるぽ"
end

save!は失敗時に例外を返す。

@hoge = Hoge.new(:name => "piyo")
begin
  @hoge.save!
  p "ゆっくりしていってね!"
rescue
  p "ぬるぽ"
end

トランザクション内(ロールバック可能)の時は、ふつうはsave!。

@hoge = Hoge.new(:name => "piyo")
begin
  Hoge.transaction do
    @hoge.save!
  end
  p "ゆっくりしていってね!"
rescue
  p "ぬるぽ"
end

ちなみにtransactionを生やしてるクラスはHogeってより、親クラスなので、以下な感じでいいかも。

@hoge = Hoge.new(:name => "piyo")
begin
  ActiveRecord::Base.transaction do
    @hoge.save!
  end
rescue => ex
  logger.error("【例外発生】:" + ex.message + "\n" + ex.backtrace.join("\n"))
end

form関連

↑ページトップへ

  • 特定のモデルに結びついたform_for, text_field、そうではない時のform_tag, text_filed_tag。
  • text_fieldの場合、パラメータやキーもハッシュ化される(params[:aaa][:bbb])。
<%= form_for(@foo) do |f| %>
  <%= f.text_field :name %>
  <%= f.submit %>
<% end %>
# create アクション
@foo = Foo.new(params[:foo])

# update アクション
@foo = Foo.find(params[:id])
@foo.update_attributes(params[:foo])

クラスとか

↑ページトップへ

  • @はじまりがインスタンス変数、@@はじまりがクラス変数、$はじまりがグローバル変数(宣言は不要)。
  • アルファベット大文字 ([A-Z]) で始まる識別子は定数。
class Sequence
  include Enumerable # Enumerable モジュールのメソッドを読み込む。

  # 自動的に呼び出される初期化メソッド。
  def initialize(from, to, by)
    @from, @to, @by = from, to, by # @始まりのインスタンス変数に多重代入。
  end

  def length
    return 0 if @from > @to
    Integer( (@to - @from) / @by ) + 1
  end

  # 別名登録
  alias size length
end
class Point
  attr_accessor :x, :y # セッタとゲッタを設定。(以前はattrだけだった)
  # attr_reader :x, :y # イミュータブル(値を変更しない)ならこちら。

  @@n = 0 # 作成したPointの数

  def initialize(x, y)
    @x, @y = x, y
  end

  def self.report
    p "作成されたPointの数=#@@n"
  end
end

p = Point.new(0, 0)

selfが付くとクラスメソッド、付かないとインスタンスメソッド

インスタンスメソッドは、インスタンスを生成してそこからでないと呼べない。
クラスメソッドなら、(インスタンスを作成せずに)そのまま呼べる。

class Benri
  def plus_one

  end

  def self.plus_two

  end

ちなみに、クラスメソッドの中でのselfはクラスを指し、インスタンスメソッド内ではそのインスタンスを指す。

privateと書いた行より後のメソッドはプライベート(上にパブリックメソッドがある)。

nil? empty? blank? present?

  • nilは存在しない、emptyは入れ物はあるけど空っぽ、nilとemptyを合わせたのがblank、blankの反対がpresent。

Rails

↑ページトップへ

ActiveSupport

↑ページトップへ

Railsのもっとも汎用的なライブラリ。

require 'active_support'

nil?とempty?はrubyのメソッドで、blank?とpresent?はrailsで拡張されたメソッド。
blank?は、nilも空も半角スペース/タブ/改行もtrue。

" ".blank?
=> true
# 複数形化
"card".pluralize
 => "cards"
# 単数形化
"cards".singularize
 => "card"

"ActiveRecord::Base".undersocre
=> "active_record/base"
"active_record/base".camelize
=> "ActiveRecord::Base"

"ActiveRecord::Base".constantize
=>  ActiveRecord::Base

# 変数から定数
SAKAI = 'yugo'
p 'SAKAI'.constantize
=> "yugo"

# モデル.new
'sakai_report'.camelize.constantize.new
Time.days_in_month(2, 2000)
=> 29
Time.days_in_month(2, 2011)
=> 28
['a', 'b', 'c'].to_json
=> ["a", "b", "c"]
{:name => 'Tama', :type => 'Cat'}.to_json
=> {"name":"Tama","type":"Cat"}
121.multiple_of?(11)
=> true
122.multiple_of?(11)
=> false

ActiveRecord

↑ページトップへ

クラス=テーブル、属性=カラム。
クラス=ActiveRecord::Baseの派生クラス。app/models配下に配置。

Railsは複合主キーには対応していません。開発を簡単にするために、複合主キーは避けるのがよいでしょう。レガシーデータベースを使うといった制約がある場合は、一意になるプライマリキーを新しく追加するなどして回避するのがおすすめです。

class User < ActiveRecord::Base
  set_table_name  :kaiin
  set_primary_key :member_code
end
# INSERT
user = User.new(:name => ‘Taro’, :email => ‘taro@everyleaf.com’)
user.save

# 違う書き方
user = User.new
user.name = 'Taro'
user.email = 'taro@everyleaf.com'

# 更新
user = User.find(requested_id)
user.name = ‘Jiro’
user.save

# 削除
user = User.find(requested_id)
user.destroy
# 特定IDのレコード参照
user = User.find(requested_id)
User.find(1)
User.last
User.find(1, 2)

# 1000件(初期値)ずつ取得して1件ずつループ。
User.find_each do |user|
  …
end

# 5000件ずつに変更。
User.find_each(:batch_size => 5000) do |user|
  …
end

# 検索
User.all(:conditions => [‘age = ?’, 31])
User.all(:conditions => [‘age = ?’, 31], :order => ‘created_at desc’, :limit => 20)

User.where(:age => 31)
User.where(:age => [31, 32])
User.where(:age => 30..40) # 範囲

# プレースホルダ
User.where('age = ? AND name = ?', 31, 'jugyo')

Ruby and Perl

↑ページトップへ

Ruby Perl
#!ruby
'hello'
%q{hello}
%q!hello!

"hello\n"
%Q{hello\n}
%Q!hello\n!

%w{a bb ccc d}

%x{ls}
#!perl
'hello'
q{hello}
q!hello!

"hello\n"
qq{hello\n}
qq!hello\n!

qw{a bb ccc d}

qx{ls} # = `ls`
<<EOS
あいうえお
かきくけこ
EOS
<<EOS
あいうえお
かきくけこ
EOS
<<'EOS'
あいうえお
かきくけこ
EOS
<<'EOS'
あいうえお
かきくけこ
EOS
<<"EOS"
あいうえお
かきくけこ
EOS
<<"EOS"
あいうえお
かきくけこ
EOS
# 末尾の識別子(EOS)の行頭にインデントが可能。
<<-"EOS"
あいうえお
かきくけこ
  EOS
#
<<"EOS"
print(Kconv.tosjis(<<"EOS"))
あいうえお
かきくけこ
EOS
#
name = '鈴木' + '一郎'
my $name = '鈴木' . '一郎';
name = '鈴木';
print("私は#{name}です。")
print("私は#{30 + 6}才です。")
my $name = '鈴木';
print "私は@{[ $name ]}です。";
print "私は@{[ 30 + 6 ]}才です。";
'あ' * 10
'あ' x 10
name = '鈴木'
name << '一郎'
# 以下も同じ。
name.concat('一郎')
my $name = '鈴木';
$name .= '一郎';
10進数  214
 2進数  0b11010110
 8進数  0326
16進数  0xD6
10進数  214
 2進数  0b11010110
 8進数  0326
16進数  0xD6
3_420_500
3_420_500
# 四則演算等
+ - * / % **
# 四則演算等
+ - * / % **
# 引数をそのまま出力。
print "abc\n"
# 末尾に改行をつけて出力。
puts 'abc'
# 引数が文字列の時ダブルクオートで囲って出力。
p 'abc'
#
# コメント

=begin
複数行
=end
# コメント

=for comment
複数行
=cut
# 変数の1文字目数字NG
# 変数に使えない予約語の例
BEGIN    class    ensure   nil      self     when
END      def      false    not      super    while
alias    defined? for      or       then     yield
and      do       if       redo     true
begin    else     in       rescue   undef
break    elsif    module   retry    unless
case     end      next     return   until
#
num += 2
num -= 2
num *= 2
num /= 2
num %= 2
num **= 2
num += 1
num -= 1
$num += 2;
$num -= 2;
$num *= 2;
$num /= 2;
$num %= 2;
$num **= 2;
$num ++;
$num --;
# falseとnilは偽
# falseとnil以外は全て真
#
# 関係演算子
== != > >= < <=

# 論理演算子
&& || !
# 関係演算子
== != > >= < <=

# 論理演算子
&& || !
# thenは省略可。
if num == 10 then
  p 'a'
elsif num == 20 then
  p 'b'
else
  p 'c'
end

unless num == 5 then
  p 'd'
end

flag = result > 10 ? 1 : 0

p 'e' if debug
p 'e' unless debug
if (num == 10) {
  print 'a';
}
elsif (num == 20) {
  print 'b';
}
else {
  print 'c';
}

unless (num == 5) {
  print 'd';
}

my $flag = $result > 10 ? 1 : 0;

print 'e' if $debug;
print 'e' unless $debug;
array = [2005, 2006, 2007, 2008]
p array[0]
p array.at(0)

array[0] = 1999

size = array.length
my @array = (2005, 2006, 2007, 2008);
print $array[0];

$array[0] = 1999;

my $size = scalar @array;
for value in array do
  p value
end

array.each{|value|
  p value
}
for my $value (@array) {
  print $value;
}
hash = {'name' => 'sakai', 'address' => 'Tokyo'}
p hash['name']
p hash.fetch('name')

hash['tel'] = '0123'
hash.store('tel', '0123')
my %hash = (name => 'sakai', address => 'Tokyo');
print $hash{name};

$hash{tel} = '0123';
hash.each{|key, value|
  p key + ' -> ' + value
}

hash.each_key{|key|
  p key + ' -> ' + hash[key]
}
while (my ($key, $value) = each %hash) {
  print $key . ' -> ' . $value;
}

for my $key (keys %hash) {
  print $key . ' -> ' . $hash{$key};
}
def print_hello
  p 'hello'
  return 1
end

def print_message(text)
  p text
end

def print_message(text = 'MESSAGE')
  p text
end

def print_message(*texts)
  texts.each{|text|
    p text
  }
end
sub print_hello {
  print 'hello';
  return 1;
}

sub print_message {
  my $text = shift @_;
  print $text;
}

sub print_message {
  my $text = shift @_ || 'MESSAGE';
  print $text;
}

sub print_message {
  my $texts = shift @_ || [];
  for my $text (@$texts) {
    print $text;
  }
}
value1, value2 = method(3, 7)
my ($value1, $value2) = method(3, 7);
# 整数→浮動小数点数
num.to_f
# 浮動小数点数→整数(小数点以下切り捨て)
f.to_i

num.round # 四捨五入
num.ceil # 大きい方へ
num.floor # 小さい方へ

num.to_s # 文字列へ
num.to_s(2) # 2進数へ
num.to_s(8) # 8進数へ
#
class Person
  def initialize(person_name='カー')
    @name = person_name
  end

  attr_accessor :name
end

person = Person.new()
person.name = 'sakai'
p person.name

# attr_accessorの他にattr_reader, attr_writerがあり。
my $person = Person->new;
$person->name('sakai');
print $person->name;

package Person;

sub new {
  my $class = shift;
  my $name = shift;
  my $self = {
    name => $name
  };
  return bless $self, $class;
}

sub name {
  my $self = shift;
  if (my $name = shift) {
    $self->{name} = $name;
    return $self;
  }
  return $self->{name};
}

1;
# 継承とスーパメソッドの呼び出し
class Baker < Person
  def work
    super
    p 'bake'
  end
end
package Baker;
parent 'Person';

sub new {
  my $class = shift;
  bless {}, $class;
}

sub work {
  my $self = shift;
  $self->SUPER::work;
  print 'bake';
}
text = 'hello';
chars = text[1, 2];
my $text = 'hello';
$chars = substr $text, 1, 2;
array.length
array.flatten
array.uniq
array.compact
array.delete(val)
array.delete_at(ind)
array.delete_if {|x| x % 2 == 0 }
array.reverse
array.sort
array.sort {|a, b| a <=> b }
#
t = Time.now
p t.year
p t.month
p t.day
p t.strftime("%Y-%m-%d %H:%M%S")
#
rbenv
gem
Bundler
plenv
cpanm
Carton
b = a.push(5) # あるいは b = a << 5 # 末尾に追加
b = a.pop # 末尾を削除
b = a.shift # 先頭を削除
b = a.unshift(5) # 先頭に追加
my @b = push @a, 5; # 末尾に追加
my $b = pop @a; # 末尾を削除
my $b = shift @a; # 先頭を削除
my @b = unshift @a, 5; # 先頭に追加
text = "aa-bb-cc"
array = text.split("-") or array = text.split(/-/)
array = text.split # 空白系文字で分割(先頭と末尾の空白系文字も消す)
array = text.split("")

text = array.join("/")
text = array.join
my $text = 'aa-bb-cc';
my @array = split /-/, $text;
my @array = split /\s+/, $text;
my @array = split //, $text;

my $text = join '/', @array;
my $text = join '', @array;
# 構文チェック
ruby -c test.rb
# 構文チェック
perl -c test.pl
#
#

表記ルール抜粋

↑ページトップへ

# 真偽値を返すメソッド名は、動詞または形容詞に`?'を付け、形容詞に `is_'は付けない。
visible?

# 破壊的なメソッドと非破壊的なメソッドの両方を提供する場合、破壊的なメソッドには`!'を付ける。
split
split! # splitの破壊的バージョン