読者です 読者をやめる 読者になる 読者になる

u16suzuの blog

u16suzu のブログです。

[キーワード引数] キーワード引数の使い方メモ

  • よく忘れるのでキーワード引数の使い方のメモ.
  • 2.1からarg1のようにキーワード引数のデフォルト引数は省略できるようになった.
def foo( arg1: , arg2: "arg2")
  puts "#{arg1} #{arg2}"
end

# 定義時に省略したarg1は呼び出し時には省略できない.(ArgumentErrorが発生する) arg2は省略できる
foo(arg1: "arg1")
# => arg1 arg2

foo(arg1: "a1", arg2: "a2")
# => a1 a2

unknown keyword の例外を抑制する ** 引数

  • キーワード引数に指定していない引数を呼び出し時に指定すると、ArgumentErrorになるが、**引数 を指定することにより解消できる.
  • もしも、メソッド内で使用しない場合 **引数 の引数名は省略できる. (エラーを抑制したい時に使う?)
def foo(arg1:, **others)
  p arg1, others
end

foo( arg1: 1, arg2: 2)

def bar(arg1: **) # 使わない時は省略可
end
  • メソッドの呼び出し時に引数が何なのかがよくわからなくなるので、キーワード引数を積極的に使っていきたい。

参考リンク

enumのメモ

定義

class Log < ActiveRecord::Base
  enum reason: { login: 0, purchase: 1, finish_game: 2 }
end

呼び出し

  • 以下のように書いておくと、後から変更が必要になった時にわかりやすい
pry(main)> Log::reasons[:login]
=> 0
  • 全部欲しい場合
pry(main)> Log::reasons
=> { login: 0, purchase: 1, finish_game: 2 }

Rubyのメタプログラミングメモ

Classをインスタンス化する時にHashで渡した値でInitializeするクラスのテンプレート

class Person
  attr_accessor :name, :age, :address

  def initialize( hash={})
    if block_given?
      yield( self )
    else
      hash.each do |k, v|
        public_send("#{k}=", v) if respond_to?("#{k}=")
      end
    end
  end

  def to_s
    instance_variables.map do |ivar|
      value = self.send( ivar.to_s.tr("@", ""))
      "#{ivar}: #{value}"
    end.join(", ")
  end
end

p1 = Person.new({name: "taro", age: 20, address: 'tokyo'})
puts p1

p2 = Person.new do |f|
  f.name = "jiro"
  f.age  = 30
  f.address = "tokyo"
end
puts p2

class Man < Person
end

p3 = Man.new do |m|
  m.name ="saburo"
  m.age = 30
  m.address = "yokohama"
end
puts p3

p4 = Man.new({name: "shiro", age: 33, address: "oosaka"})
puts p4

クラスマクロ

  • 例外用のクラスマクロを定義した親クラスのテンプレート
class ExceptionBase < StandardError
  @_code

  def self.code(code=nil) # 引数がnilの時はgetter, nilでない時はsetterになる
    @_code ||= code
  end

  def code
    self.class.instance_variable_get("@_code")
  end
end

class NotFoundException < ExceptionBase
  code 404
end

class ForbiddenException < ExceptionBase
  code 403
end

p NotFoundException.code # => 404
p NotFoundException.new.code #=> 404

p ForbiddenException.code # => 403
p ForbiddenException.new.code # => 403

後で読む

空白で区切って指定したフィールドの文字を取得

$ echo "1 2 3" | cut -d " " -f3
3

参考: フィルタを使用した文字列操作 2 | UNIX & Linux コマンド・シェルスクリプト リファレンス

  def check_names names
    return unless Hash === names

    invalid_options =
      names.keys.map { |k| k.to_sym } - [:rdoc, :clobber_rdoc, :rerdoc]

    unless invalid_options.empty? then
      raise ArgumentError, "invalid options: #{invalid_options.join ', '}"
    end
  end

今日は、rdoc の task.rbを読んだ。これは、名前をチェックするメソッドで、 hashのキーが指定したものだけであることをチェックしている。

Rubyの特殊変数メモ

  • $! : 最後に発生した例外オブジェクト
  • $: : Rubyライブラリの検索パス, $LOAD_PATH
  • $0 : 実行中のRubyスクリプトのfile名
  • $/ : 区切り文字
  • $, : デフォルトの出力フィールド区切り文字列

  • 参考: module Kernel (Ruby 2.1.0)

Classをインスタンス化する時にHashで渡した値でInitializeする

Classをインスタンス化する時にHashで渡した値でInitializeする

class Person
  attr_accessor :name, :age, :address

  def initialize( hash={})
    if block_given?
      yield( self )
    else
      hash.each do |k, v|
        public_send("#{k}=", v) if respond_to?("#{k}=")
      end
    end
  end

  def to_s
    instance_variables.map do |ivar|
      value = self.send( ivar.to_s.tr("@", ""))
      "#{ivar}: #{value}"
    end.join(", ")
  end
end

p1 = Person.new({name: "taro", age: 20, address: 'tokyo'})
puts p1

p2 = Person.new do |f|
  f.name = "jiro"
  f.age  = 30
  f.address = "tokyo"
end
puts p2


class Man < Person
  def initialize(hash={})
    super(hash)
  end
end

puts Man.new({name: "saburo", age: 25, address: "saitama"})