Testing the pattern that always return a new instance of object
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.gitignore
LICENSE
README.md
lazy_calculator.rb
lazy_calculator_test.rb

README.md

lazy_calculator

In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. Wikipédia.

Inspirado pelo ótimo 20,000 Leagues Under ActiveRecord, decidi tentar implementar uma classe que utiliza a tática de lazy initialization para postergar um processamento, teoricamente, custoso. A idéia, tal qual acontece com o ActiveRecord (explicado no post linkado) é ir adicionando condições à um objeto para, posteriormente, executar uma tarefa.

Para exemplificar, criei a LazyCalculator. Uma calculatora que armazena as condições (por hora, apenas adição e subtração) e, quando solicitada, calcula o resultado.

require_relative "lazy_calculator"

calculator = LazyCalculator.new
=> #<LazyCalculator:0x007fbbe31a7ee8 @numbers=[], @operations=[]>

calculator.plus(5)
=> #<LazyCalculator:0x007fbbe31a7ee8 @numbers=[5], @operations=[:+]>

calculator.minus(2)
=> #<LazyCalculator:0x007fbbe31a7ee8 @numbers=[5, 2], @operations=[:+, :-]>

irb(main):006:0> calculator.calc
=> 3

Obviamente a complexidade da LazyCalculator nem se compara com a do ActiveRecord. Mas acho que a idéia fica bem clara nos exemplos acima. Observe que os métodos plus e minus retornam a instância do própria objeto. Isso possibilita o encadeamento de vários métodos (method chaining):

calculator = LazyCalculator.new

calculator.plus(5).minus(1).minus(9).plus(1).calc
=> -3

Também fica bem claro como o método calc é postergado até o momento em que é realmente necessário. Quando executado, ele verifica os valores e operações que já existem no objeto atual e realiza o cálculo.

Eu já havia observado esse comportamento no ActiveRecord, mas ainda não havia tirado um tempo para dar uma olhada com mais calma. Esse tipo de solução me agrada, simples e efetiva, utilize em seu código sempre que parecer conveniente.