@@ -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.
283314class 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 }
288319end
289320```
290321
@@ -319,7 +350,7 @@ require 'digest'
319350class 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
606637person.attribute(:first_name ) # "John"
607638person.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?
690721end
691722
@@ -717,7 +748,7 @@ attribute :name, accept: :present? # "expected to be present?"
717748attribute :name , reject: :empty? # "expected to not be empty?"
718749attribute :name , accept: String # "expected to be a kind of String"
719750attribute :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" }
749780end
750781
751782User .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
766797end
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'
785816end
786817
787818User .new (age: ' x' , name: nil )
@@ -803,9 +834,9 @@ require 'digest'
803834class 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