Hi there, I have a question about lazy initialization accessor methods that always keep me thinking in terms of performance and style. For years I did something like: MyClass>>#property property isNil ifTrue: [ self initializeProperty ]. "It could be ifNil: as well" ^property MyClass>>#initializeProperty "Returns the receiver, not the property." property := self foo collect: [:e | ... ]. But this made me think that maybe I'm performing extra operations, so I started doing something like: MyClass>>#property ^property ifNil: [ self initializeProperty ] MyClass>>#initializeProperty ^property := self foo collect: [:e | ... ] The initialize method is often created by an "Extract Method" refactoring I do in the accesor, where I do the initial implementation. The messages makes me think that the second implementation is "faster", but an initializationMethod returning the value instead of the receiver is a code smell to me. I early initialize everything I know will be be used right away, but for cases it doesn't make sense. What do you think/prefer? Why? Maybe we could use the reified variables (slots) to implement the lazy initialization themselves :) Best regards! Esteban A. Maringolo |
Seems like either way would have unmeasurable performance impact for your application vs the other and you should go for whats most legible/comprehensible.
On that metric I prefer the first but #yolo
|
In reply to this post by Esteban A. Maringolo
Personally I prever to avoid long lazy initializations, so I have it nice and tidy in a single method.
MyClass>>#property ^ property ifNil: [ property := self bar collect: #food ] If I want to initialize the value in a separate method (typically for testing or reuse), then I prefer to avoid state mutation there and instead I return the result. MyClass>>#property ^ property ifNil: [ property := self createNewProperty ] MyClass>>createNewProperty "I won't touch property instance variable here, just create a new value and return it" ^ self bar collect: [ :e | e drink ] > an initializationMethod returning the value instead of the receiver is a code smell to me. For this reason I tend to name such methods createNewX, initializeX says to me "only mutate state and return self" Peter |
In reply to this post by Paul DeBruicker
I know the compiler is smart enough in most cases, and even if it isn't, an extra send or two won't hurt me in the kind of computation I do.
But it's the style what "worried" me the most. Let's use the first then :) Esteban A. Maringolo 2017-08-05 19:18 GMT-03:00 Paul DeBruicker <[hidden email]>: Seems like either way would have unmeasurable performance impact for your |
In reply to this post by Peter Uhnak
2017-08-05 19:21 GMT-03:00 Peter Uhnak <[hidden email]>:
> If I want to initialize the value in a separate method (typically for testing or reuse), then I prefer to avoid state mutation there and instead I return the result. > > MyClass>>#property > ^ property ifNil: [ property := self createNewProperty ] > > MyClass>>createNewProperty > "I won't touch property instance variable here, just create a new value and return it" > ^ self bar collect: [ :e | e drink ] > > > > an initializationMethod returning the value instead of the receiver is a code smell to me. > > For this reason I tend to name such methods createNewX, initializeX says to me "only mutate state and return self" I like this approach very much, it makes the accessor code concise and separates the implementation of the property creation. Thank you! Esteban A. Maringolo |
+1. It also avoids having to dive a level deeper in a debugger when you want to inspect the current value vs initial value without modifying state. For naming, I tend to use one of several depending on the use; a) initialX b) defaultX c) calculateX depending on whether the property is a) expected to change value during the lifetime of the object b) have an optional value provided at creation, then be static c) always be calculated (ie, an instvar used to cache expensive results used often) Cheers, Henry |
I favour this approach :) and… I consider it the “standard approach” for what goes into Pharo itself. Esteban
|
Free forum by Nabble | Edit this page |