LoginSignup
3
1

More than 3 years have passed since last update.

マルチスケール特論 第7回

Posted at

ruby-2.7.1p83

ruby

rubocop

ruby の linter.rubocop -A hoge.rb で自動的に良い感じに修正してくれる

emacs

以下を.emacs とかに書いとけば、save時に rubocop が走って、自動で修正してくれる。便利。

(defun rubocop ()
  (when (eq major-mode 'ruby-mode)
    (shell-command-to-string (format "rubocop -A %s" buffer-file-name))))
(add-hook 'after-save-hook 'rubocop)

.zero?

year % 4 == 0(year % 4).zero? は同値らしい?前者の書き方だと rubocop に怒られる

frozen_string_literal: true

rubocop で Missing frozen string literal comment って怒られた。ファイル先頭に # frozen_string_literal: true というコメントを挿入すると warning は消える。Ruby 3.0 から文字列リテラルが default で immutable になるかららしい。でも文字列リテラルを破壊的変更しても無意味じゃない?

leap_year

うるう年判定をする。

# frozen_string_literal: true

def leap?(year)
  if (year % 400).zero?
    true
  elsif (year % 100).zero?
    false
  elsif (year % 4).zero?
    true
  else
    false
  end
end

def leap2?(year)
  (year % 400).zero? || !(year % 100).zero? && (year % 4).zero?
end

条件式がない case は if にされる

def leap?(year)
  case
  when (year % 400).zero? then true
  when (year % 100).zero? then false
  when (year % 4).zero? then true
  else; false
  end
end

上のコードも rubocop を通すと以下に修正される(case の条件式がないので)。

def leap?(year)
  if (year % 400).zero? then true
  elsif (year % 100).zero? then false
  elsif (year % 4).zero? then true
  else; false
  end
end

nonzero?

Numeric#zero? の否定っぽい Numeric#nonzero? が存在するが、これは罠で、返り値が nil だったり self だったりする。大人しく zero? の否定をとる。

test code

minitest を使う。

# frozen_string_literal: true

require 'minitest/autorun'
require_relative 'check_leap_year'

class SampleTest < Minitest::Test
  def test_leap
    assert_equal true, leap?(2000)
    assert_equal false, leap?(1900)
    assert_equal true, leap?(2004)
  end

  def test_leap2
    assert_equal true, leap2?(2000)
    assert_equal false, leap2?(1900)
    assert_equal true, leap2?(2004)
  end
end
Run options: --seed 54297

# Running:

..

Finished in 0.000727s, 2750.6571 runs/s, 8251.9712 assertions/s.

2 runs, 6 assertions, 0 failures, 0 errors, 0 skips

test 成功。

leap と leap2 が同値かをテスト

tests = [1900, 2000, 2004, 1999]
p tests.map { |t| leap?(t) }.zip(tests.map { |t| leap2?(t) }).all? { |years| years[0] == years[1] }

tests の要素 t に対して(map)、leap?(t) と leap2?(t) の結果を(zip)years に格納(years って名前、ナンセンスだった)して、それら2つが同じ値か比較していって、一つでも false があれば false、全て true なら true が返る(all?)。

FILE

python でいう、

if __name__ == "__main__":
    main()

をやりたくて以下のように書いたんだけど、

if __FILE__ == $0
  main
end

rubocop が言うには

main if __FILE__ == $PROGRAM_NAME

が良いらしい。


  • source ~/ghq/github.com/TeamNishitani/grad_members_20f/members/syasin-5d/7th.org
3
1
1

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
3
1