[ruby-core:113744] [Ruby master Feature#19708] Support `attr_reader :foo?`
From:
"AMomchilov (Alexander Momchilov) via ruby-core" <ruby-core@...>
Date:
2023-06-03 00:23:29 UTC
List:
ruby-core #113744
Issue #19708 has been updated by AMomchilov (Alexander Momchilov).
You can workaround this by using `attr_reader` to create the optimized method, `alias_method` to give it the nice `active?` name, and then `remove_method` to delete the original non-`?` name:
```ruby
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(ivar_name)
alias_method(predicate_name, ivar_name)
remove_method(ivar_name)
end
end
```
Usage:
```ruby
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)() Untitled 2.rb:6>
```
----------------------------------------
Feature #19708: Support `attr_reader :foo?`
https://bugs.ruby-lang.org/issues/19708#change-103391
* Author: AMomchilov (Alexander Momchilov)
* Status: Open
* Priority: Normal
----------------------------------------
Creating reader methods with `attr_reader` is preferable over defining them by hand, not only because it's more convenient, but also because it hits a fast path in MRI (see `VM_METHOD_TYPE_IVAR`).
Since local and instance variables can't end with `?`, you can't use `attr_reader` to define predicate-style methods for boolean values, like:
```ruby
class Person
attr_reader(:name, :age, :active?) # invalid attribute name `active?' (NameError)
def initialize
@name = "Bob"
@age = 30
@active = true
end
end
```
It would be nice if `attr_reader` (and friends) could behave like:
```ruby
def active? = @active
```
(`attr_writer` and `attr_accessor` couldn't do the same, since `def active?=(new_value)` isn't valid, so they'd probably stick with `def active=(new_value)`)
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/