🦔

[Feature #19708] attr_reader で :foo? みたいな名前が指定できるようにする提案

2024/05/24に公開

[Feature #19708] Support attr_reader :foo?

  • 以下のように attr_reader では active? のようなゲッターメソッドを定義する事ができないのでできるようにしたいというチケット
class Person
  attr_reader :name, :age, :active? # invalid attribute name `active?' (NameError)

  # 以下のようなメソッドとして定義されると嬉しい
  # def active? = @active

  def initialize
    @name = "Bob"
    @age = 30
    @active = true
  end
end
  • この要望はよく来ているんですが今回のチケットでは以下の事が理由として上げられている
    • atter_reader を使用してゲッターメソッドをつくることが推奨されている
    • MRI として atter_reader を使ったほうが高速になる
  • 上記を回避する場合は以下のようなペルパーメソッドを使う必要があると提示されている
module PredicateHelper # Or just monkey-patch Module, I won't sue :D
  def define_predicate(predicate_name)
    ivar_name = predicate_name.to_s.delete_suffix("?")
    # メソッド呼び出しを最適化するために attr_reader で定義したメソッドを別名で alias したりしてるぽい?
    attr_reader(ivar_name)
    alias_method(predicate_name, ivar_name)
    remove_method(ivar_name)
  end
end

class Person
  extend PredicateHelper

  attr_reader :name, :age
  define_predicate :active?

  def initialize
    @name = "Bob"
    @age = 30
    @active = true
  end
end

bob = Person.new

p [bob.name, bob.age, bob.active?] # ["Bob", 30, true]

# Shows that `#active?` is just aliasing the now-deleted `#active`
p Person.instance_method(:active?) # => #<UnboundMethod: Person#active?(active)() /tmp/v38jtQf/26:5>
  • これ系はいままでも何度かチケットが立っているんですが Reject はされているんですよねえ…
  • とはいえほしいのはほしいのでなんとか matz を説得できないものか
GitHubで編集を提案

Discussion