On 26.04.2009 19:40, Tim Conner wrote:
> Hi,
> I am trying to create a model (BatchExternalBooking) which has the
> following methods:
> BatchExternalBooking.message_thread_1=
> BatchExternalBooking.message_thread_1
> BatchExternalBooking.message_thread_2=
> BatchExternalBooking.message_thread_2
> .. etc all the way upto
> BatchExternalBooking.message_thread_x=
> BatchExternalBooking.message_thread_x
> 
> I assume that I need to do this via method_missing because I don't know
> how many of these methods I will actually need.
> 
> My code currently looks like this:
> class BatchExternalBooking
>   def method_missing(method_sym, *args)
>     if method_sym.to_s =~ /^message_thread_([0-9]*)=?(\w*)?$/
>       BatchExternalBooking.instance_eval "attr_accessor
> :message_thread_#{$1}"

You might rather want to use class_eval here.

Also, as Robert pointed out already, using $1 only once and storing the 
value in a local variable is safer because it can be changed by any 
method you invoke.

>       self.send("message_thread_#{$1}=", $2)
>     else
>       super
>     end
>   end
> end
> 
> However, this is not working.  See below:
>>> b = BatchExternalBooking.new
> => #<BatchExternalBooking:0x3e54040>
>>> b.message_thread_1 = 45
> => 45
>>> b.message_thread_1
> => ""
> The value wasn't actually set but the attr_accessor correctly created
> the setter method.  If I try and set the variable again, it works:
>>> b.message_thread_1 = 45
> => 45
>>> b.message_thread_1 
> => 45
> 
> Why isn't the setter working the first time round?
> 
> Thanks a lot.

Is there a reason that you do not use OpenStruct or an ordinary Array 
for this?  It seems you are indexing by number anyway so why not use an 
Array?

Kind regards

	robert