条件判断

条件判断とは

ある条件のときには○○という処理を、そうでないときには××という処理をさせたい、というときに使うのが条件判断文です。
条件判断文には大きく3つあります。

  • if文
  • unless文
  • case文

ですが、これらを説明する前に比較演算子と論理演算子を紹介します!

◆比較演算子
比較演算子とは、等号「==」や不等号「>」「<」のことです。比較演算の結果はtrueかfalseでかえってきます。

a == b
aとbは一致するか?
a != b
aとbは不一致か?
a >= b
a≧bか?
a <= b
a≦bか?
a > b
a>bか?
a < b
a<bか?


◆論理演算子
論理演算子は高校数学で習った「かつ」「または」のことです。これもtrueかfalseでかえってきます。
「かつ」は「&&」、「または」は「||」で表します。

条件1 && 条件2
どちらの条件もtrueだった場合に全体もtrueになります。どちらか一方でもfalseの場合は全体もfalseになります。
条件1 || 条件2
どちらかの条件がtrueだった場合に全体もtrueになります。

また、比較演算子でも出てきた「!」は否定の論理演算子です。
「!条件」は条件の真偽を反転させます。つまり、条件がfalseだった場合はtrueに、trueだった場合はfalseになります。

演算子には優先順位がありますので、条件を書くときは注意してください。

高

::
[]
+(単項演算子)、!、~
**
-(単項演算子)
*、/、%
+、-
<<、>>
&
|、^
>、>=、<、<=
<=>、==、===、!=、=~、!~
&&
||
?:(条件演算子)
..、...
=(+=、-=、*=、/=などを含む)
not
and、or

低

◆if文
条件判断文を紹介します。
最も基本的な条件判断文がこのif文で、以下のように書きます。
thenは省略可能です。

if 条件文 (then)
  条件文がtrueだったときに実行する内容
end

「条件文がtrueだったらif〜endで囲まれている文の内容を実行してください」
という意味になります。

これにelsif、elseを加えると、以下のような分岐を書くことが出来ます。

if 条件1
  条件1がtrueだったときに実行する内容A →falseなら条件2へ
elsif 条件2
  条件2がtrueだったときに実行する内容B →falseなら条件3へ
elsif 条件3
  条件3がtrueだったときに実行する内容C →falseならelseへ
else
  どの条件もfalseだったときに実行する内容D
end

elsifの後ろには条件文を書くことが出来ますが、elseの後ろには書けないので注意してください。
この条件に合致するかは上から順番に見ていくので、条件文をどの順番で書くかも大事になってきます。

◆unless文
unless文はif文と丁度反対の役割をする条件判断文です。

unless 条件文
  条件文がfalseだったときに実行する内容
end

「条件文がfalseだったらunless〜endで囲まれている文の内容を実行してください」
という意味になります。
これも同じようにelsif、elseを書くことが出来、分岐の仕方も同じです。
また、if文とunless文は裏表の関係なので以下のように書くことが出来ます。

unless 条件文
  実行内容A
else
  実行内容B
end

↓↑

if 条件文
  実行内容B
else
  実行内容A
end

これはまったく同じ処理を表しています。

if文もunless文も、実行したい式の後ろに書くことも出来ます。
これはもちろんif文やunless文で書くことが出来ます。

print "aはbよりも大きい" if a > b
↓↑
if a > b
  print "aはbよりも大きい"
end

◆case文
条件がいくつもある場合ifとelsifを使って書くことも出来ますが、比較したいオブジェクトが一つだけでそのオブジェクトの値によって場合分けをしたい場合、case文を使ったほうがシンプルで分かりやすくなります。

case 比較したいオブジェクト
when 値1
  値1がtrueだったときに実行する内容A →falseなら次の文へ
when 値2
  値2がtrueだったときに実行する内容B →falseなら次の文へ
when 値3
  値3がtrueだったときに実行する内容C →falseなら次の文へ
else
  どれもfalseだったときに実行する内容D
end

これをif文で書くと以下のようになります。

if 対象オブジェクト === 値1 then
  値1と一致する場合に行う処理
elsif 対象オブジェクト === 値2 then
  値2と一致する場合に行う処理
elsif 対象オブジェクト === 値3 then
  値3と一致する場合に行う処理
else
  どの値にも一致しない場合に行う処理
end
ex.

sum = 0
product = "Apple"

case product
when "Melon" then   # "Apple"は"Melon"ではないので、
  sum = sum + 500  # 次の条件文に行きます。
when "Apple" then
  sum = sum + 150  # product = "Apple"とwhen "Apple"が合致するので、
end         # 以下のように返されます。

print("料金は", sum, "です")
# => 料金は150です

また、whenには一度に複数の値を指定出来ます。
複数の値に対して同じ処理を実行する場合は、「when」の後に値をカンマ(,)で区切って並べて記述します。以下の例では「値1(Melon)」「値2(Banana)」に一致した場合は同じ処理を行い、「値3(Apple)」「値4(Lemon)」「値5(Orange)」に一致した場合は同じ処理を行います。

sum = 0
product = "Banana"

case product
when "Melon","Banana" then
  sum = sum + 500
when "Apple","Lemon","Orange" then
  sum = sum + 150
end

print("料金は", sum, "です")
# => 料金は500です


最後までお読み頂きありがとうございます!

変数と定数

後輩への引き継ぎに向けて、rubyの基本的なところについてまとめていきます。
お付き合いいただけますと幸いです。


変数

変数とは、オブジェクト(もの)につける名札のようなものです。
中学校の数学で、以下のような式を習ったかと思います。

x = a + b

ここでいうxは変数、aとbは定数として、
この式は「a + bをxと呼びます」と宣言しているわけです。

すると以下のような式が出てきたとき、xにa + bという値を代入して計算出来ますよね。

y = x + c
この式はx = a + bであるため、
y = a + b + c
と言い換えることが出来る。

これと似たようなことをrubyでも行っています。
書き方は一緒です。

変数名 = オブジェクト

ex.

num = 10
これは「"10"を"num"と呼びます」と宣言しています。

最初は「変数ってなんだかいまいちわからそ(´・ω・`)」って人もいるかと思いますが、実はたったこれだけのことだったりするんです。


◆変数の種類
rubyには4種類の変数があります。

何が違うの!ヽ(`Д´)ノって思うかもしれませんが、変数の適用範囲が違うだけで基本は一緒です。
以下一つずつ説明していきます。

  • ローカル変数
  • ローカル変数とは、言葉のとおり適用範囲の狭い変数です。 どのくらい狭いかというと、メソッド内でしか適用されません。

    ex.
    
    def hoge
      number = "123456"
      p number    # => "123456"
    end
    
    def fuga
      p number    # => error!!
    end
    

    このように、hogeメソッド内では変数numberを呼び出せるけどfugaメソッド内ではエラーが出てしまいます。
    逆に言えば、ローカル変数なら同じ名前をつけても別のメソッドだと違う内容を表せるということです。

    ex.
    
    def hoge
      number = "1234"
      p number    # => "1234"
    end
    
    def fuga
      number = "5678"
      p number    # => "5678"
    end
    


  • グローバル変数
  • グローバル変数はローカル変数の反対の変数です。
    プログラム中のどこで使われても、同じ名前であれば必ず同じ変数として扱われます。
    グローバル変数には変数名の頭に$マークをつけます。

    ex.
    
    def hoge
      $apple = "りんご"
      p $apple    # => "りんご"
    end
    
    def fuga
      p $apple    # => "りんご"
    end
    


  • インスタンス変数

  • インスタンス変数は、同じインスタンス内であればメソッドを越えて使うことができます。
    変数名の頭に@マークをつけて使用します。



  • クラス変数

  • クラス変数は、そのクラスやサブクラス、それらのインスタンスで共有できる変数のことです。
    変数名の頭に@@をつけて使用します。

    ex.
    
    class HelloWorld
      @@foo = "foo"       # クラス変数
    
      def hoge
        @baa = "baa"      # インスタンス変数
        piyo = "piyo"     # こっちはローカル変数
      end
    end
    

定数

定数は変数と同様に名札の働きをしますが、中学校の数学で習ったものと一緒で内容を変更することは出来ません。
irbで一度代入した定数の中身を変更しようとすると怒られます。
定数はすべて大文字アルファベットで書きます。

ex.

[irb]
>> NUMBER = 1    # NUMBERは定数。
=> 1
>> NUMBER = 2    # NUMBERは1です、と宣言しているので
          変更しようとすると怒られます。
warning: already initialized constant NUMBER = 2


以上です。
最後までお読み頂きありがとうございます!

vimrcの設定方法

vimのpluginを入れてみて、他にも色々設定したいと思ってぐぐってみると、vimrcに〜〜を書けばおkみたいな記事をたくさん見かけます。
vimから:scriptnamesでプラグインを見てみると一番上にvimrcがいるので、それを編集してみようと開いてみると読み込み専用モードで編集できない(´;ω;`)


ので、調べてみました。vimrcの設定方法!


vimの設定ファイルは「.vimrc」というファイルです。エディタを起動するとホームディレクトリにある.vimrcを読み込むことになってますが、ホームディレクトリに.vimrcがない場合には「/etc/vim/vimrc」を読み込みます。私が最初に編集しようとして出来なかったやつです。
なので、ホームディレクトリに.vimrcを作成するか、/etc/vim/vimrcを.vimrcに名前を変更してホームディレクトリにコピーして使用します。ホームディレクトリに置いた設置ファイルは隠しファイルなので注意してください。「vimrc」ではなく「.vimrc」です。


まず設定ファイルをコピーします。

$ cp /etc/vim/vimrc /home/hoge/.vimrc

次に.vimrcの所有者、グループをユーザ(ここではfuga)に変更し、パーミッションも変更します。

$ chown fuga /home/hoge/.vimrc
$ chgrp fuga /home/hoge/.vimrc
$ chmod 600 /home/hoge/.vimrc

これでユーザ権限でファイルの編集が出来るようになりました。


以下のコマンドを打ち込んでファイルを開いてみましょう。

$ vi .vimrc


これで色々と設定が可能になりました!


vimrcの詳しい設定内容については以下を参考にさせていただきましたm(_ _)m

  1. .vimrcの設定 - web探検隊
  2. Vim初心者的導入メモ 2/3 「vimrc設定」編



最後までお読みいただきありがとうございます!

vimプラグイン導入の導入

vimを使い始めてようやく操作にも慣れてきたので、カスタマイズしてみようとプラグインについて調べてみました。


[vim] + [プラグイン]と検索をかけるだけで、プラグインを紹介したブログがたくさんたくさんヒットします。
あ、これいいなーと思うプラグインを発見して、いざダウンロードしてみようとしても
ダウンロードの仕方が 分 か ら な い (´;ω;`)


なので、下記サイト様を参考にしながらダウンロードの方法についてまとめてみました。
http://sites.google.com/site/vimdocja/usr_05-html


Unixであることを前提として書き進めているのでご注意ください。



【手順1】
プラグインディレクトリを作りましょう。

$ mkdir ~/.vim
$ mkdir ~/.vim/plugin

これで.vimフォルダの下にpluginディレクトリが出来ました!



【手順2】
プラグインをインストールして、先ほど作ったpluginディレクトリに「〜.vim」となっているファイルをコピーする。
vimを再起動して「:scriptnames」コマンドでプラグインvimに正しく読み込まれているか確認します。



読み込まれていたらプラグインのインストール完了です!



これでおしまいです。意外と簡単でした(´∀`*)
vimプラグインの管理を簡単にする「vim-pathogen」というプラグインもあるそうなので、次はこれを導入してみたいと思います。


最後までお読みいただき、ありがとうございます!

文字化けとたたかう

私が先日はまりにはまった文字化けについてまとめてみました。


文字化けが起こる原因として考えられるのは、主に以下の3点です。

  1. ファイルがUTF-8で保存されていない
  2. MySQLの設定がUTF-8になってない
  3. そのほか
では、一つずつ見ていきましょう。


◆ファイルがUTF-8で保存されていない
まずはファイルがUTF-8で保存されているか確認してみましょう。

$ cd アプリのある場所
$ nkf -g ファイル名

Enterを押すと、文字コードの自動判別の結果を表示してくれます。

Shift-JISコードなら

$ Shift-JIS

UTF-8コードなら

$ UTF-8

など。


ここでShift-JISと表示されたら、以下のコマンドを使って変換しましょう。

$ nkf -w --overwrite ファイル名

引数に指定しているファイルをUTF-8に上書きしてくれます。


元ファイルを残したい場合は「--overwrite」は書かず、

$ nkf -w ファイル名

だけで大丈夫です。


ファイルがUTF-8になったか確認してみましょう。

$ nkf -g ファイル名

Enterを押して、UTF-8と表示されたら成功です。
これがLinux文字コードを変換する方法です。


【使い方】

$ nkf オプション ファイル [>出力ファイル]

【オプション一覧】

-g   :自動判別の結果を表示
-w   :UTF-8コードを出力(BOMなし)
-s   :Shift-JISコードを出力
-e   :EUCコードを出力
-Lu  :unix改行形式(LF)に変換
-Lw  :windows改行形式(CRLF)に変換
-Lm  :macintosh改行形式(CR)に変換
--overwrite   :引数のファイルに直接上書き


複数のファイルをまとめて変換することもできます。

  • 文字コードUTF-8に、改行をunix形式(LF)に変換
  • $ nkf -w -Lu --overwrite *.html

    .htmlでまとめて変換しています。



MySQLの設定がUTF-8になってない
Linux文字コードを変換しても駄目なら、MySQLの設定を疑ってみましょう。

まずはMySQLの設定がどうなってるか確認します。

mysql> status;

Enterを押すと、ずらーっとMySQLの設定が出てきます。

mysql> status;
--------------
mysql  Ver 14.7 Distrib 4.1.20, for redhat-linux-gnu (i386) using readline 4.3

Connection id:          36
Current database:       staff2006
Current user:           maiha@localhost
SSL:                    Not in use
Current pager:          lv
Using outfile:          ''
Using delimiter:        ;
Server version:         4.1.20
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    latin1
Conn.  characterset:    latin1
UNIX socket:            /var/lib/mysql/mysql.sock
Uptime:                 1 hour 4 min 14 sec

Threads: 2  Questions: 54354  Slow queries: 0  Opens: 468  Flush tables: 1  Open tables: 64  Queries per second avg: 14.103
--------------

すると、charactersetとついてる4行がlatin1となっているのが分かります。これをUTF-8に直しましょう。
※charactersetは文字コードの設定という意味です。今はlatin1となっていて、文字コードラテン語に設定されています。

では、文字コード関係の変数の値を見てみましょう。show variables like "char%";と打ち込むと、以下のようになるはず。

mysql> show variables like "char%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

変数を見てみると「character_set_system」だけがUTF-8になっています。
「/etc/my.cnf」の設定を変更して他の変数もすべてUTF-8にしましょう。

まず、インストールしたMySQLの中のサンプルをコピーします。

$ cp /usr/local/mysql/support-files/my-medium.cnf /etc/my.cnf

「cp」はコピーを意味します。
このコマンドは、
「/usr/local/mysql/support-files/」という階層にある「my-medium.cnf」というファイルを
「/etc/」という階層の中に「my.cnf」という名前でファイルコピーをしてください、という意味になります。


これを入力後、etcディレクトリに移動します。

$ cd /etc

次に、my.cnfを編集します。

$ vi my.cnf

Enterを押すと

E325: ATTENTION
 ・・・・
-- More --

と表示されるので、Enterを押し続けます。
すると「--More--」の部分が「[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (D)elete it:」となるので、キーボードでEを押してください。
ファイルの中身が表示されて、内容を編集できるようになりました。
キーボードの↓キーもしくはjキーでスクロールをして[mysqld]の箇所に行き、

[mysqld]
default-character-set=utf8
skip-character-set-client-handshake

を入力します。
これは1行目でデフォルトの文字コードを指定し、2行目で「余計なことをするな」と命令しています。

続けてescボタンを押し、「:w」コマンドを入力してEnterを押すと、my.cnfが上書き保存されました。
「:q」コマンドを入力してviを終了します。
サーバの設定を変更したので、MySQLを再起動しましょう。
最後にもう一度show variables like "char%";と打ち込んで、変更されたか確認しておきます。

mysql> show variables like "char%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

これでMySQLの設定がUTF-8になりました。



◆そのほか
これでもダメならRails上でファイルの設定をしましょう。
app/controllers/application.rbにbefore_filterを追加します。

class ApplicationController < ActionController::Base
...

  before_filter :set_charset

  private
  def set_charset
    @headers["Content-Type"] = "text/html; charset=UTF-8"
  end

...
end

これでもダメなら!
私の場合はこれでもダメでした。
テストでHTMLの要素の検証を行おうとテストメソッドを書いていたら何度も何度もエラーが出てくるのです。
上記設定を何度試してもダメだったので、最終的に以下のようにコードを書きました。

def test_method
  ...
  ...
  assert @response.body.toutf8.include?("#{@user.name}")
end

裏ワザにはなりますが、エラーは解消されたので結果オーライかなと。




長くなりましたが以上です。
最後までお読みいただきありがとうございます!

テストスクリプトの動かし方

テストスクリプトについて。


スクリプトの実行をする前に準備をしましょう。


◆テスト用データベースの準備

Railsではデータベースを3種類用意します。開発用、テスト用、本番用の3つです。テスト用のデータベースを別に用意することで、開発用や本番用のデータベースに影響を与えることなく、データベースに書いては消し書いては消し、といったテストのための処理が行えます。

まずは開発用のデータベースからテスト用データベースにスキーマ定義(テーブルとフィールド定義)をコピーしましょう。

コマンドプロンプト

$ rake db:test:prepare

これでdbフォルダにschema.rbというファイルが作成されます。
※特定のDBMSに固有のデータ型(例えばMySQLのLONGBLOB)を使っている場合や外部キー制約を定義している場合に、コピーが上手くいかなくなります。この問題を防ぐために、以下のとおりコメントアウトを外しておきましょう。

@/config/environment.rb

# config.active_record.schema_format = :sql
↓
  config.active_record.schema_format = :sql

◆テスト用データベースの中身を用意

テーブルの中身はフィクスチャファイルで作成します。
テスト用のフィクスチャファイルは、testフォルダの下のfixturesフォルダに置くことが決まっています。
データベース名.yml」というファイルが自動的に出来てるので、それを編集します。

  • レコードに具体的な名前をつけておくと、単体テストスクリプトで「member(:taro)」のように分かりやすい形でオブジェクトを取り出すことができます。

テストスクリプトを実行する度にフィクスチャからテスト用のデータベースにデータが読み込まれるため、フィクスチャからデータを取り込む作業は必要ありません。これによって、テストを行う度に初期状態のテーブルが利用できるようになります。



◆テストスクリプトの実行

いよいよテストスクリプトの実行です。
まずはコマンドを紹介していきます。

  • 1つずつテスト
  • * モデルのテスト
    $ sudo ruby test/unit/○○_test.rb

    * コントローラのテスト
    $ sudo ruby test/functional/○○_controller_test.rb

    * --nameオプションをつけると、特定のテストメソッドだけテストできます
    $ sudo ruby test/unit/○○_test.rb --name = test_△△

    * Admin::□□ Controllerの場合
    $ sudo ruby test/functional/admin/□□_controller_test.rb

  • テストをまとめて実行
  • * 単体テスト
    $ sudo rake test:units

    * 機能テスト
    $ sudo rake test:functionals

    * 統合テスト
    $ sudo rake test:integration

  • 全部まとめて
  • $ sudo rake test


次回はアサーションメソッドについてまとめます。
最後までお読みいただきありがとうございます!

テストについて

テストについてまとめていきます。


そもそもテストとは、コードを書いてブラウザで表示させて確認してエラーが出たらそれを修正してまたブラウザで確認して、、という手動テストを自動化する機能です。


◆テストの種類

  • 単体テスト(unitテスト):モデルやヘルパーのテスト
  • 機能テスト(functionalテスト):コントローラのテスト
  • 統合テスト(integrationテスト):実際のリクエストをシミュレートするテスト



◆では、何をテストするのか?

  • 単体テスト
  • * モデルの検索系メソッド(findなど)が正しいデータを取得できるか
    * モデルの更新系メソッド(saveなど)が正しくデータベースの状態を変化させるか
    * モデルの更新系メソッドが不正な入力に対して適切なエラーを発生させるか(値の検証の確認)
  • 機能テスト
  • * 適切なテンプレートが選択されているか
    * インスタンス変数に適切な値が格納されているか
    * 適切にレンダリングされているか、あるいは適切なURLにリダイレクトされているか
    * 更新系のアクションが正しくデータベースの状態を変化させるか
  • 統合テスト
  • * 例えば、ログインして名簿に新しいメンバーを追加してログアウトする、といった一連の動きをテストする


統合テストはユーザが使う流れで、あんまりテストは書きません。機能テストにそういったことも書けてしまうということもあります。



テスト駆動開発について

テストはバグを調べるために行うだけでなく、機能を実装する前にテストを行うこともできます。仕様を明確にするためにテストをつくり、テストを通すためにコーディングを行うというスタイルのことをテスト駆動開発と呼びます。

テスト駆動開発では、以下のサイクルを何度も繰り返すことで開発が進みます。

①テストを書く
ある機能が正しく実装されていれば成功し、そうでなければ失敗するようなテストスクリプトを作る。
⇒機能が動く条件を定める = 仕様決め


②テストが失敗することを確認
テストスクリプトを実行
∟成功⇒テストスクリプトが上手く書けていない
∟失敗⇒エラーの表示を詳しく調べ、
 テストスクリプト自体のバグやデータベースの設定ミス等による失敗でないか確認


③テストが成功するよう実装
実際のコーディング。目標はテストを通すこと。
この段階では多少コードが汚くてもOK。


リファクタリング
コードをきれいにする。
「テストが成功する」という状態を維持したままプログラムを書き換える。
変数名を変える、長すぎるメソッドを分割する、コードの重複部分を除く、など。


①テストを書く


②...以下繰り返し

テスト駆動開発によって単純な短いサイクルを繰り返せば、コーディングの目標が明確になり、プログラマの負担を減らすことが出来ます。





次回はテストスクリプトについて説明します。
最後までお読みいただきありがとうございます!