needs() shares default values among instances

9 views
Skip to first unread message

tobyo

unread,
Apr 22, 2012, 3:08:21 PM4/22/12
to ere...@googlegroups.com
The latest commit to needs.rb seems to indicate that such an issue was fixed, but here's what occurs with version 0.9.0.pre1

jirb
irb(main):062:0> require 'rubygems'
=> false
irb(main):063:0> require 'erector'
=> true

irb(main):066:0> class Sprocket < Erector::Widget
irb(main):066:0>   needs :foo => 'A'
irb(main):067:1>   def content
irb(main):068:2>     @foo.succ!
irb(main):069:2>     p "@foo is #{@foo}"
irb(main):070:2>   end
irb(main):071:1> end
=> nil

irb(main):072:0> x = Sprocket.new
=> #<Sprocket:0x1649b1a @foo="A", @_block=nil, @_assigns={}>
irb(main):073:0> x.to_html
=> "<p>@foo is B</p>"
irb(main):074:0> x.to_html
=> "<p>@foo is C</p>"
irb(main):075:0> x.to_html
=> "<p>@foo is D</p>"

irb(main):076:0> y = Sprocket.new
=> #<Sprocket:0x46fef3 @foo="D", @_block=nil, @_assigns={}>
irb(main):077:0> y.to_html
=> "<p>@foo is E</p>"


This is particularly problematic if you wanted to assign an empty array or hash as the default.  The workaround is to avoid needs() default values and instead assign defaults in a constructor.

Perhaps this is more of a feature than a bug, but I think it's rare one would want to have multiple widget instances point to the same instance unless it is something like a formatter class or something to that effect. It would generally make more sense to dup() each default value.

Perhaps it would be nice to allow passing a proc/lambda to needs() that is evaluated for each new Widget instance. Of course, that doesn't let you directly default to a proc.

needs :a_string => proc { 'A' }
needs :a_proc => proc { proc{ 'A' } }

Thoughts?

Viktor Trón

unread,
Nov 11, 2012, 1:25:29 PM11/11/12
to ere...@googlegroups.com


On Sunday, April 22, 2012 8:08:21 PM UTC+1, tobyo wrote:
This is particularly problematic if you wanted to assign an empty array or hash as the default.  The workaround is to avoid needs() default values and instead assign defaults in a constructor.

Perhaps this is more of a feature than a bug, but I think it's rare one would want to have multiple widget instances point to the same instance unless it is something like a formatter class or something to that effect. It would generally make more sense to dup() each default value.

Perhaps it would be nice to allow passing a proc/lambda to needs() that is evaluated for each new Widget instance. Of course, that doesn't let you directly default to a proc.

needs :a_string => proc { 'A' }
needs :a_proc => proc { proc{ 'A' } }

This issue is fixed but I agree that specifying defaults with procs called on the widget instance would be super useful.
it is easy and natural fix
Vik

Reply all
Reply to author
Forward
0 new messages