LoginSignup
12
0

More than 3 years have passed since last update.

【Week 7】gem, ruby_third

Last updated at Posted at 2020-12-02

はじめに

マルチスケールシミュレーション特論の講義メモです.講義メモのインデックスはコチラ

今回の参考資料はチャート式ruby-appendix-III(bundler)チャート式ruby-III(if, case, Array.each by leap year)です.

チャート式 Ruby

参照記事はコチラ

if-else, case, array and each

閏年判定プログラム

プログラミング初心者に条件分岐を教えるとき,題材としてよく挙げられるのが閏年.今年2020年は閏年だったが,一体どれくらいの人が気にしていたのだろうか.恐らく大半はプログラミング初学者で条件分岐習った人(偏見).

それはともかく,閏年の判定プログラムを作成したい.閏年は

  1. 4で割り切れる年.
  2. ただし,100 で割り切れる年は閏年でない.
  3. しかし,400 で割り切れる年は閏年.

の条件によって判定される.なぜこのような条件なのかは,気持ちに余裕があれば追記する.

参照記事にあるとおり閏年の判定は ひねくれた 複雑な条件分岐であるため,あらかじめ考えて実装するのは面倒.そこで今回は順を追って TDD (テスト駆動開発)で実装していく.

if-elsif-else-end

まず Ruby における if 文の文法をおさえておく.条件分岐といえば if 文というくらい重要な項目ではあるが,言語によって若干仕様が異なってくるので,多少プログラミングに慣れていても注意が必要である.

if  then
   ...
elsif  then
   ... 
...
else
   ... 
end

それでは閏年判定プログラム check_leap_year.rb を作成していく.はじめに 1. 4で割り切れる年 であれば true を返すようなプログラムを実装する.

p year = ARGV[0].to_i
if year%4==0 then
  p true
end

試しに 2004 を引数として実行すると,

> ruby check_leap_year.rb 2004
2004
true

期待通り true を返した. 4で割り切れない 1999 を引数として実行すると,

> ruby check_leap_year.rb 1999
1999

このとき,true は出力されない.このように4で割り切れない年であれば false を返すようにしたい.else 文を用いて以下のように編集する.

p year = ARGV[0].to_i                                                                          
if year%4==0 then                                                                              
  p true                                                                                       
else                                                                                           
  p false                                                                                      
end       

実行すると,

> ruby check_leap_year_0.rb 1999
1999
false

期待通り false を返した.

array, each

ここで2. 100 で割り切れる年は閏年でない

[1900,2004,1999].each do |year|
  p year
  if year % 100 ==0
    p false
  elsif year % 4 == 0
    p true
  else
    p false
  end
end
> ruby check_leap_1900_2004_1999.rb 
1900
false
2004
true
1999
false

3. 400 で割り切れる年は閏年

def leap?(year)
  if year % 400 ==0
    p true
  elsif year % 100 ==0
    p false
  elsif year % 4 == 0
    p true
  else
    p false
  end 
end

[2000, 1900, 2004, 1999].each do |year|
  p year
  leap?(year)
end
> ruby check_leap_year.rb
2000
true
1900
false
2004
true
1999
false

case

case 
when  ..., then
  ..
when '*'  then
  ..
else
  ..
end
def leap?(year)
  case 
  when year == 2000 ; p true
  when year == 1900 ; p false
  when year == 2004 ; p true
  else              ; p false
  end
end
[2000, 1900, 2004, 1999].each do |year|
  p year
  leap?(year)
end

三項演算子 (ternary operator)

def leap?(year)
  return  (year%400 == 0) ? true :
    (year%100 == 0) ? false :
    (year%4 == 0) ? true : false
end

[2004, 1999, 1900, 2000].each do |year|
  p year
  p leap?(year)
end

Ruby 開発周辺情報

参照記事はコチラ

shebang

前回の講義で作成し,UI-like にリファクタリングしたプログラム hello.rb を実行ファイルにしたい.これはシバン (shebang) を設定し,ファイルの権限を変更することで実現できる.

> cp hello.rb hello
# hello.rb を hello にコピー

> emacs hello
# hello を編集

プログラムのはじめにシバンを設定する.

#! /usr/bin/env ruby
def puts_hello name...end
def gets_name ...end

name = gets_name
puts_hello name

hello_rudy.rb に実行権限を付与する.

> chmod a+x hello
または
> chmod 755 hello

> ./hello Rudy
Hello Rudy.

期待どおり実行ファイル hello を作成することができた.

gem

bundler

shebang だと PATH を通したり実行環境を整えるのに手間がかかる.そこで実行ファイルを gem にすることで容易に呼び出せるようにしたい.

gem を作成するには bundler を使って環境を構築する必要がある.まずは参照記事どおり bundler をインストールし,gem 作成用のファイル環境を構築する.

> sudo gem install bundler
Password:
Successfully installed bundler-2.1.4
Parsing documentation for bundler-2.1.4
Done installing documentation for bundler after 2 seconds
1 gem installed

> bundle gem hello_rudy -b
Creating gem 'hello_rudy'...
MIT License enabled in config
Code of conduct enabled in config
      create  hello_rudy/Gemfile
      create  hello_rudy/lib/hello_rudy.rb
      create  hello_rudy/lib/hello_rudy/version.rb
      create  hello_rudy/hello_rudy.gemspec
      create  hello_rudy/Rakefile
      create  hello_rudy/README.md
      create  hello_rudy/bin/console
      create  hello_rudy/bin/setup
      create  hello_rudy/.gitignore
      create  hello_rudy/.travis.yml
      create  hello_rudy/test/test_helper.rb
      create  hello_rudy/test/hello_rudy_test.rb
      create  hello_rudy/LICENSE.txt
      create  hello_rudy/CODE_OF_CONDUCT.md
      create  hello_rudy/exe/hello_rudy
Initializing git repo in ~/grad_members_20f/members/e79a93e5b7b1/codes/hello_rudy
Gem 'hello_rudy' was successfully created. For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html

hello_rudy というディレクトリが作成され,そこに gem の作成に必要なファイルが生成される.その中のひとつに .git という隠しディレクトリが存在するが,今回は必要ないので削除しておく.

これで gem を作成するファイル環境は構築できた.続いて,実行ファイル hello_rudy が実行できるように編集していく.

> rm -rf hello_rudy/.git

> cd hello_rudy
> bundle exec exe/hello_rudy 
bundler: not executable: exe/hello_rudy

> chmod a+x exe/hogehoge
> bundle exec exe/hello_rudy
bundler: failed to load command: exe/hello_rudy (exe/hello_rudy)
Gem::InvalidSpecificationException: The gemspec at ~/grad_members_20f/members/e79a93e5b7b1/codes/hello_rudy/hello_rudy.gemspec is not valid. Please fix this gemspec.
The validation error was 'metadata['homepage_uri'] has invalid link: "TODO: Put your gem's website or public repo URL here."'

> emacs hello_rudy.gemspec 

エラー内容の該当ファイル hello_rudy.gemspec を編集する必要がある.

spec.summary spec.description spec.homepage の3つは "TODO:~" の部分を削除し,内容に沿って適宜編集する.また, spec.metadata["homepage_uri"] spec.metadata["source_code_uri"] spec.metadata["changelog_uri"] はコメントアウトしておく.

require_relative 'lib/hello_rudy/version'

Gem::Specification.new do |spec|
  spec.name          = "hello_rudy"
  spec.version       = HelloRudy::VERSION
  spec.authors       = ["e79a93e5b7b1"]
  spec.email         = ["e79a93e5b7b1@xxx.com"]

  spec.summary       = %q{Hello Rudy.}
  spec.description   = %q{Hello Rudy.}
  spec.homepage      = "https://github.com/TeamNishitani/grad_members_20f/member/e79a93e5b7b1"
  spec.license       = "MIT"
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")

  spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"

  # spec.metadata["homepage_uri"] = spec.homepage
  # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
  # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."

編集を保存した後,再度実行してみる.

> bundle exec exe/hello_rudy
> emacs lib/hello_rudy.rb

エラーもなくなり,問題なく hello_rudy を実行できるようになった.本題の "Hello xxx." を出力するプログラムは /hello_rudy/lib/hello_rudy.rb に記述する.

require "hello_rudy/version"

module HelloRudy
  class Error < StandardError; end
  # Your code goes here...
  puts "Hello #{ARGV[0]}."
end

プログラムを保存した後,引数を付け足して実行してみる.問題なく出力されれば gem をインストールする.

> bundle exec exe/hello_rudy Rudy
Hello Rudy.

> sudo rake install:local
Password:
hello_rudy 0.1.0 built to pkg/hello_rudy-0.1.0.gem.
hello_rudy (0.1.0) installed.

> hello_rudy Rudy
Hello Rudy.

問題なく実行ファイルを gem にすることができた.

Directory_tree

bundle を用いることで以下のようなファイル環境が自動で作成された.

> tree
.(hello_rudy)
├── CODE_OF_CONDUCT.md
├── Gemfile
├── Gemfile.lock
├── LICENSE.txt
├── README.md
├── Rakefile
├── bin
│   ├── console
│   └── setup
├── exe
│   └── hello_rudy
├── hello_rudy.gemspec
├── hello_rudy.gemspec~
├── lib
│   ├── hello_rudy
│   │   └── version.rb
│   ├── hello_rudy.rb
│   └── hello_rudy.rb~
├── pkg
│   └── hello_rudy-0.1.0.gem
└── test
    ├── hello_rudy_test.rb
    └── test_helper.rb

6 directories, 17 files

次回の講義内容 <2020-11-11 Wed>

次回の講義は

だそうです.


  • source ~/grad_members_20f/members/e79a93e5b7b1/posts/class/c7_20201104.org
12
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
0