Ruby の基本コマンドと周辺技術について


最近、初めて Ruby でコードを書く機会があったので、Ruby の基本的なコマンドや、周辺技術についてまとめてみました。Ruby の文法についてはここでは触れません。

Ruby とは1995年に日本で開発されたオブジェクト志向スクリプト言語です。国内のスタートアップの企業の約1/4が自社サービスの開発に Ruby を採用していると言われており、PHPと並んで人気の言語となっています。また Ruby には高度なエコシステムが形成されており、フレームワークの開発やチームによる開発にも向いている言語と言われています。

Ruby には標準で以下のようなコマンドが用意されています。

rbenv

Ruby の環境設定を行うコマンドです。

Ruby のバージョン表示します。

rbenv --version

インストールされているRuby のバージョン一覧を表示します。

rbenv versions

Ruby のバージョンの選択します。

rbenv global 2.2.2

irb

Ruby のコードをインタプリタで実行するツールです。irb という名前は Interactive Ruby に由来しています。

irb を起動します。

irb

Ruby のコードを1行、1行実行できます。

※実行例
irb

ruby

ruby とは Ruby で書かれたコードを実行するコマンドです。

以下のようにソースファイルを指定して実行します。

ruby helloworld.rb

helloworld.rb

print("Hello World")

gem

gem とは Ruby で書かれたライブラリのことを指しており、gem を管理するコマンドも gem となっています。英語で宝石を意味する gem に由来しています。gemname.gemspec (gemname の部分は実際には gem の名前に置き換わります。)に gem に関する説明や、gem の依存関係を記述します。

gem のインストール

gem install gemname

gem のアンインストール

gem uninstall gemname

ローカルの gem をビルドします

gem build gemname.gemspec

ビルドした gem をインストールします

gem install ./gemname-0.1.0.gem

インストール済みの gem リスト表示

gem list --local

gemname.gemspec の内容

# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'my_gem_miura/version'

Gem::Specification.new do |spec|
  spec.name          = "my_gem_miura"
  spec.version       = MyGemMiura::VERSION
  spec.authors       = ["Kotaro Miura"]
  spec.email         = ["miura@at-iroha.jp"]

  spec.summary       = %q{Clac your age}
  spec.description   = %q{This is an AIIT student's test program in Japan.}
  spec.homepage      = "http://aiit.ac.jp"
  spec.license       = "MIT"

  # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
  # delete this section to allow pushing this gem to any host.
  if spec.respond_to?(:metadata)
    spec.metadata['allowed_push_host'] = "http://mygemserver.com"
  else
    raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
  end

  spec.files         = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
  spec.bindir        = "exe"
  spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
  spec.require_paths = ["lib"]

  spec.add_development_dependency "bundler", "~> 1.10"
  spec.add_development_dependency "rake", "~> 10.0"
  spec.add_development_dependency "rspec"
end

RubyGems

RubyGems とは Ruby のパッケージ管理システムです。RubyGems には誰もがライブラリを登録することができ、登録されたライブラリは gem コマンドにて簡単にインストールすることができます。

https://rubygems.org/

rubygems

Rake

Rake とは Make によく似た機能を持つ Ruby で書かれたシンプルなビルドツールです。Rakefile を元にビルドを行います。

rake のインストール

gem install rake

Rakefile の記述例

require "bundler/gem_tasks"
require "rake/testtask"

Rake::TestTask.new(:test) do |t|
  t.libs << "test"
  t.libs << "lib"
  t.test_files = FileList['test/**/*_test.rb']
end

task :default => :test

パターンにマッチしたタスクの短い説明を表示します

rake -T

テストを実行します

rake test

ビルドを実行します

rake build

Bundler

Bundler とはライブラリの依存関係の管理する技術です。gem は更新頻度が高く、バージョンによってプログラムが正常に動作しなくなる場合があります。その問題を解決するのが Bundler となります。Bundler は GemFile の記述を元に各種ライブラリを自動的にダウンロードします。bundle コマンドにて各種操作を行います。

Bundler の使い方

Gemfile のひな形を作成します。

bundle init

Gemfile に以下のように記述します。

source 'https://rubygems.org'
gem 'nokogiri'
gem 'rspec'

Gemfile の記述を元にインストールします。

bundle install

#bundle コマンドで gem を作成します。

bundle gem gemname

Minitest

Minittest とは Ruby に標準で搭載されている単体テストライブラリです。最近では Minitest よりもさらに高機能な RSpec も広く使われています。

テストコードの作成例

require 'test_helper'
require 'gem_minitest'

class GemMinitestTest < Minitest::Test
	def setup
		@my = GemMiniTest.new
	end

	#oddメソッドテスト
	#整数を入力として受け取り,値が奇数ならば真を返す
	def test_odd
		assert_equal(false, @my.odd(0))
		assert_equal(true,  @my.odd(1))
		assert_equal(false, @my.odd(2))
	end

	#check_numberメソッドテスト
	def test_check_number
		assert_equal(false, @my.check_number(0))
		assert_equal(false, @my.check_number(123))
		assert_equal(false, @my.check_number(1001))
		assert_equal(true,  @my.check_number(1000))
	end

	#enough_lengthメソッドテスト
	def test_enough_length
		#境界値チェック2,3,8,9桁
		assert_equal(false, @my.enough_length("12"))
		assert_equal(true,  @my.enough_length("123"))
		assert_equal(true,  @my.enough_length("12345678"))
		assert_equal(false, @my.enough_length("123456789"))
	end

	#divideメソッドテスト
	def test_divide
		assert_equal(2, @my.divide(50, 25))
		assert_equal(20, @my.divide(200, 10))
	end

	#fizz_buzzメソッドテスト
	def test_fizz_buzz
		assert_equal("",         @my.fizz_buzz(0))
		assert_equal("",         @my.fizz_buzz(1))
		assert_equal("Fizz",     @my.fizz_buzz(3))
		assert_equal("",         @my.fizz_buzz(4))
		assert_equal("Buzz",     @my.fizz_buzz(5))
		assert_equal("",         @my.fizz_buzz(14))
		assert_equal("FizzBuzz", @my.fizz_buzz(15))
		assert_equal("",         @my.fizz_buzz(16))
		assert_equal("",         @my.fizz_buzz(101))
	end

	#引数に数値を1 つとる.3 の倍数の時は”Fizz”を返す.5 の倍数の時は”Buzz”を返す.3 と5 の公倍数のときは”FizzBuzz”を返す.
	def test_hello
		assert_output(/Hello/) { @my.hello}
	end
end

テストするコード

require "gem_minitest/version"

class GemMiniTest
	require 'time'
	require 'prime'
	
	#整数を入力として受け取り,値が奇数ならば真を返す
	def odd(num)
		if (num % 2)==1 then
			return true
		else
			return false
		end
	end
	
	#引数が0 以外ではじまる4 桁の数字であり,なおかつ,値が偶数ならば真を返す
	def check_number(num)
		#0チェック
		if num==0 then
			return false
		end
		
		#桁チェック
		if num.to_s.length != 4 then
			return false
		end
		
		#偶数チェック
		if odd(num) then
			return false
		else
			return true
		end
	end
	
	#文字列を受け取り,その長さが3 文字以上,8 文字以下であれば真を返す
	def enough_length(str)
		#最小値チェック
		if str.length < 3 then
			return false
		end
		
		#最大値チェック
		if str.length > 8 then
			return false
		end
		
		return true
	end
	
	#引数として割る数と割られる数を取り,割り算をした結果を返す.ただし,0 で割り算をしたら例外を発生する
	def divide(num_n, num_d)
		return (num_n / num_d).to_f
	end
	
	#引数に数値を1 つとる.3 の倍数の時は”Fizz”を返す.5 の倍数の時は”Buzz”を返す.3 と5 の公倍数のときは”FizzBuzz”を返す.
	def fizz_buzz(num)
		if num==0 then
			return ""
		end
		
		if (((num % 3)==0) && ((num % 5)==0)) then
			return "FizzBuzz"
		end
		
		if (num % 3)==0 then
			return "Fizz"
		end
		
		if (num % 5)==0 then
			return "Buzz"
		end
		
		return ""
	end
	
	#引数に数値を1 つとる.3 の倍数の時は”Fizz”を返す.5 の倍数の時は”Buzz”を返す.3 と5 の公倍数のときは”FizzBuzz”を返す.
	def hello()
		puts "Hello"
	end
end

テストの実行

rake test

Guard

Guard とはファイルの変更などを監視し、タスクを自動的に実行するツールです。例えばエディタでソースコードを変更した際に、自動的にテストを実行させたい場合などに利用します。

Gemfile に guard を追加します

#開発環境でのみ guard を追加
group :develeoment do
  gem 'guard'
end

Guardfile のひな形を作成します

bundle exec guard init

以下の様なファイルが自動生成されます。watch の部分などを環境に応じて変更します。

guard :minitest do
# with Minitest::Unit
  watch(%r{^test/(.*)\/?test_(.*)\.rb$})
  watch(%r{^lib/(.*/)?([^/]+)\.rb$})     { |m| "test/#{m[1]}#{m[2]}_test.rb" }
  watch(%r{^test/test_helper\.rb$})      { 'test' }

# with Minitest::Spec
# watch(%r{^spec/(.*)_spec\.rb$})
# watch(%r{^lib/(.+)\.rb$})         { |m| "spec/#{m[1]}_spec.rb" }
# watch(%r{^spec/spec_helper\.rb$}) { 'spec' }

# Rails 4
# watch(%r{^app/(.+)\.rb$})                               { |m| "test/#{m[1]}_test.rb" }
# watch(%r{^app/controllers/application_controller\.rb$}) { 'test/controllers' }
# watch(%r{^app/controllers/(.+)_controller\.rb$})        { |m| "test/integration/#{m[1]}_test.rb" }
# watch(%r{^app/views/(.+)_mailer/.+})                   { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
# watch(%r{^lib/(.+)\.rb$})                               { |m| "test/lib/#{m[1]}_test.rb" }
# watch(%r{^test/.+_test\.rb$})
# watch(%r{^test/test_helper\.rb$}) { 'test' }

# Rails < 4
# watch(%r{^app/controllers/(.*)\.rb$}) { |m| "test/functional/#{m[1]}_test.rb" }
# watch(%r{^app/helpers/(.*)\.rb$})     { |m| "test/helpers/#{m[1]}_test.rb" }
# watch(%r{^app/models/(.*)\.rb$})      { |m| "test/unit/#{m[1]}_test.rb" }
  end

  guard :bundler do
  require 'guard/bundler'
  require 'guard/bundler/verify'
  helper = Guard::Bundler::Verify.new

  files = ['Gemfile']
  files += Dir['*.gemspec'] if files.any? { |f| helper.uses_gemspec?(f) }

# Assume files are symlinked from somewhere
  files.each { |file| watch(helper.real_path(file)) }
  end

  guard :minitest do
# with Minitest::Unit
  watch(%r{^test/(.*)\/?test_(.*)\.rb$})
  watch(%r{^lib/(.*/)?([^/]+)\.rb$})     { |m| "test/#{m[1]}test_#{m[2]}.rb" }
  watch(%r{^test/test_helper\.rb$})      { 'test' }

# with Minitest::Spec
# watch(%r{^spec/(.*)_spec\.rb$})
# watch(%r{^lib/(.+)\.rb$})         { |m| "spec/#{m[1]}_spec.rb" }
# watch(%r{^spec/spec_helper\.rb$}) { 'spec' }

# Rails 4
# watch(%r{^app/(.+)\.rb$})                               { |m| "test/#{m[1]}_test.rb" }
# watch(%r{^app/controllers/application_controller\.rb$}) { 'test/controllers' }
# watch(%r{^app/controllers/(.+)_controller\.rb$})        { |m| "test/integration/#{m[1]}_test.rb" }
# watch(%r{^app/views/(.+)_mailer/.+})                   { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
# watch(%r{^lib/(.+)\.rb$})                               { |m| "test/lib/#{m[1]}_test.rb" }
# watch(%r{^test/.+_test\.rb$})
# watch(%r{^test/test_helper\.rb$}) { 'test' }

# Rails < 4
# watch(%r{^app/controllers/(.*)\.rb$}) { |m| "test/functional/#{m[1]}_test.rb" }
# watch(%r{^app/helpers/(.*)\.rb$})     { |m| "test/helpers/#{m[1]}_test.rb" }
# watch(%r{^app/models/(.*)\.rb$})      { |m| "test/unit/#{m[1]}_test.rb" }
end 

Guard を実行します

bundle exec guard

仮想環境を使用していて、ホストのテキストエディタによる変更にも反応させたい場合は、オプション -p を追加します

bundle exec guard -p

GitHub へのプッシュ方法

Ruby で開発したソースは git コマンドで直接、GitHub へプッシュすることが可能です。

Gitのリポジトリ作成を作成します。

git init

github上にリポジトリを作成

hub create

Git で管理する対象ファイルを指定します。「.」の場合、全てのファイルが対象となります。

git add .

ローカルリポジトリにコミットします。

git commit -m "first commit"

コミットした内容を GitHub 上にプッシュします。

git push -u origin master

Travis CI

Travis CI とは GitHub と連携し、GitHub 上のソースに変更が発生した場合、Travis CI に通知され、変更されたソースを自動でテストなどを行うWebサービスです。Ruby 以外にも様々な言語をサポートしています。CI は Continuous Integration (継続的統合) の略となっています。
.travis.yml ファイルに各種設定を記述します。

公式サイト
https://travis-ci.org/

GitHub 側の設定
1. プロジェクトのレポジトリを開きます。
2. [Setting] の [Werbhooks & Services] を選択します。
3. [Add Services] ボタンにて [Travis CI] を選択します。

github

Travis CI 側の画面
travis_ci

設定後、GitHub のソースファイルに変更が発生すると、Travis CI 上で自動的にテストが実行されます。

関連記事:

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です