Skip to content

Commit 425ee51

Browse files
serraduraclaude
andcommitted
README: modernize examples to use it block parameter
Adopt Ruby 3.4's `it` implicit block parameter across the README's callable examples (defaults, accept/reject validators, rejection_message lambdas, attribute block form). Add a "A note on syntax" section before the table of contents that flags both the `it` parameter (3.4+) and hash value omission (3.1+), with classic-form equivalents so Ruby >= 2.7 readers — still inside the gem's supported range — can translate back. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e3121e0 commit 425ee51

1 file changed

Lines changed: 44 additions & 13 deletions

File tree

README.md

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,37 @@ See [Feature overview](#feature-overview) for what else the gem can do.
8181
| 3.1.0 | https://github.com/serradura/u-attributes/blob/v3.x/README.md |
8282
| 2.8.0 | https://github.com/serradura/u-attributes/blob/v2.x/README.md |
8383

84+
## A note on syntax <!-- omit in toc -->
85+
86+
Examples in this README use two modern Ruby features. The gem itself supports Ruby `>= 2.7`, so if you're on an older runtime, here's how to read them back to the classic form.
87+
88+
**[`it` block parameter](https://docs.ruby-lang.org/en/3.4/syntax/methods_rdoc.html#label-Numbered+parameters)** — Ruby 3.4+
89+
90+
```ruby
91+
# Modern (Ruby >= 3.4) — what you'll see throughout this README
92+
attribute :age, default: -> { it&.to_i }
93+
attribute :name, accept: -> { it.is_a?(String) && !it.empty? }
94+
95+
# Classic — equivalent on every supported Ruby
96+
attribute :age, default: ->(value) { value&.to_i }
97+
attribute :name, accept: ->(value) { value.is_a?(String) && !value.empty? }
98+
```
99+
100+
**[Hash value omission](https://docs.ruby-lang.org/en/3.1/syntax/literals_rdoc.html#label-Hash+Literals)** — Ruby 3.1+
101+
102+
When a hash key matches an in-scope local variable (or method) name, you can drop the value:
103+
104+
```ruby
105+
name = 'Ada'
106+
age = 21
107+
108+
# Modern (Ruby >= 3.1)
109+
Person.new(name:, age:)
110+
111+
# Classic — equivalent on every supported Ruby
112+
Person.new(name: name, age: age)
113+
```
114+
84115
# Table of contents <!-- omit in toc -->
85116

86117
- [Installation](#installation)
@@ -183,7 +214,7 @@ Everything in this table is available the moment you `include Micro::Attributes`
183214
| Define an attribute | `attribute :name` | Public reader; no setter |
184215
| Define many at once | `attributes :a, :b, default: 0` | Trailing options apply to every name |
185216
| Override in a subclass | `attribute! :name, default: 'X'` | Subclass-only |
186-
| Default value | `attribute :name, default: 'X'` | Static value or `proc { ... }` / `->(v) { ... }` |
217+
| Default value | `attribute :name, default: 'X'` | Static value or `proc { it... }` / `-> { it... }` |
187218
| Required (without strict) | `attribute :name, required: true` | Raises on missing key if `attributes=` is invoked with one |
188219
| Freeze the value | `attribute :name, freeze: true` | Also `:after_dup`, `:after_clone` |
189220
| Visibility | `attribute :secret, private: true` | Or `protected: true`; hidden from `#attributes` hash |
@@ -283,8 +314,8 @@ Pass `default:` with either a static value or a callable.
283314
class Person
284315
include Micro::Attributes.with(:initialize)
285316

286-
attribute :age, default: -> v { v&.to_i }
287-
attribute :name, default: ->(name) { String(name || 'John Doe').strip }
317+
attribute :age, default: -> { it&.to_i }
318+
attribute :name, default: -> { String(it || 'John Doe').strip }
288319
end
289320
```
290321

@@ -319,7 +350,7 @@ require 'digest'
319350
class User::SignUpParams
320351
include Micro::Attributes.with(:initialize)
321352

322-
TrimString = ->(value) { String(value).strip }
353+
TrimString = -> { String(it).strip }
323354

324355
attribute :email, default: TrimString
325356

@@ -606,8 +637,8 @@ person.attribute('age') # 20
606637
person.attribute(:first_name) # "John"
607638
person.attribute('foo') # nil
608639

609-
person.attribute('age') { |value| puts value } # prints 20
610-
person.attribute('foo') { |value| puts value } # nothing — name doesn't exist
640+
person.attribute('age') { puts it } # prints 20
641+
person.attribute('foo') { puts it } # nothing — name doesn't exist
611642
```
612643

613644
`#attribute!(name)` does the same but raises on an unknown name:
@@ -685,7 +716,7 @@ class User
685716
include Micro::Attributes.with(:initialize, :accept)
686717

687718
attribute :age, accept: Integer, allow_nil: true
688-
attribute :name, accept: -> v { v.is_a?(String) && !v.empty? }, default: 'John Doe'
719+
attribute :name, accept: -> { it.is_a?(String) && !it.empty? }, default: 'John Doe'
689720
attribute :email, accept: :present?
690721
end
691722

@@ -717,7 +748,7 @@ attribute :name, accept: :present? # "expected to be present?"
717748
attribute :name, reject: :empty? # "expected to not be empty?"
718749
attribute :name, accept: String # "expected to be a kind of String"
719750
attribute :name, reject: String # "expected to not be a kind of String"
720-
attribute :name, accept: ->(v) { v } # "is invalid"
751+
attribute :name, accept: -> { it } # "is invalid"
721752
```
722753

723754
### `allow_nil:` option
@@ -745,7 +776,7 @@ class User
745776
include Micro::Attributes.with(:initialize, :accept)
746777

747778
attribute :name, accept: String, rejection_message: 'must be a string'
748-
attribute :age, accept: Integer, rejection_message: ->(key) { "#{key} must be an integer" }
779+
attribute :age, accept: Integer, rejection_message: -> { "#{it} must be an integer" }
749780
end
750781

751782
User.new(name: 1, age: 'x').attributes_errors
@@ -761,7 +792,7 @@ class FilledString
761792
end
762793

763794
def rejection_message
764-
->(key) { "#{key} can't be an empty string" }
795+
-> { "#{it} can't be an empty string" }
765796
end
766797
end
767798

@@ -781,7 +812,7 @@ class User
781812
include Micro::Attributes.with(initialize: :strict, accept: :strict)
782813

783814
attribute :age, accept: Integer
784-
attribute :name, accept: ->(v) { v.is_a?(String) && !v.empty? }, default: 'John doe'
815+
attribute :name, accept: -> { it.is_a?(String) && !it.empty? }, default: 'John doe'
785816
end
786817

787818
User.new(age: 'x', name: nil)
@@ -803,9 +834,9 @@ require 'digest'
803834
class User::SignUpParams
804835
include Micro::Attributes.with(:initialize, accept: :strict)
805836

806-
TrimString = ->(value) { String(value).strip }
837+
TrimString = -> { String(it).strip }
807838

808-
attribute :email, accept: ->(s) { s =~ /\A.+@.+\..+\z/ },
839+
attribute :email, accept: -> { it =~ /\A.+@.+\..+\z/ },
809840
default: TrimString,
810841
freeze: :after_dup
811842

0 commit comments

Comments
 (0)