# Fun with setter functions

**URL:** <https://www.ruby-forum.com/t/fun-with-setter-functions/66492>\
**Category:** Ruby\
**Created:** [August 26, 2006, 11:42am UTC](https://www.ruby-forum.com/t/fun-with-setter-functions/66492 "2006-08-26T11:42:33Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![olbrich](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/5f9b8f/32.png) [@olbrich](https://www.ruby-forum.com/u/olbrich)\
**Post date:** [August 26, 2006, 11:42am UTC](https://www.ruby-forum.com/t/fun-with-setter-functions/66492/1 "2006-08-26T11:42:33Z")

</div>

I have a setter function in a class that I would like to pass additional  
arguments to, so I can do some addtional calculations if required.

My first crack at this was to do something like…

…  
def variable=(value, options=nil)  
@variable = value  
do\_something\_cool if options == :flag  
end

Here’s the only problem, how do you pass the options?

object.variable = value, :flag  
results in  
[value, :flag] being passed to the function.

I see a couple of work arounds.

1. send works, but is ugly object.send(‘variable=’,value,:flag)
2. rewrite variable so that it expects an array and just unpack stuff  
from the array

Any other solutions I may have overlooked?

\_Kevin  
[www.sciwerks.com](http://www.sciwerks.com)

---

<div class="post-metadata">

**Author:** ![olbrich](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/5f9b8f/32.png) [@olbrich](https://www.ruby-forum.com/u/olbrich)\
**Post date:** [August 26, 2006, 4:42pm UTC](https://www.ruby-forum.com/t/fun-with-setter-functions/66492/2 "2006-08-26T16:42:50Z")

</div>

On 8/26/06, Kevin O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Any other solutions I may have overlooked?

Try

def variable=(\*args)  
@variable = args.shift  
do\_something\_cool if args.shift == :flag  
end

\*args will receive array of arguments passed in either case (i.e. both  
when one and two parameters are passed)

The latter args.shift will return nil if there are no more parameters.

Another possibility could be using hash parameters, as rails often does:

def variable=(value, options ={})  
@variable = value  
do\_something\_cool if options[:options] == :flag  
end

Call as: variable = value, :options =\> :flag

---

<div class="post-metadata">

**Author:** ![olbrich](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/5f9b8f/32.png) [@olbrich](https://www.ruby-forum.com/u/olbrich)\
**Post date:** [August 28, 2006, 11:12am UTC](https://www.ruby-forum.com/t/fun-with-setter-functions/66492/3 "2006-08-28T11:12:19Z")

</div>

On 26.08.2006 16:42, Jan S. wrote:

> > end  
> > from the array  
> > \*args will receive array of arguments passed in either case (i.e. both
> 
> Call as: variable = value, :options =\> :flag

Both approaches won’t work as Ruby does allow only exactly one argument  
to an assignment:

11:06:12 [Temp]: cat -n var.rb  
1  
2 class Foo  
3 def var=(val,\*opts)  
4 p opts  
5 @var = val  
6 end  
7  
8 def var() @var end  
9 end  
10  
11 f=Foo.new  
12 p f.var  
13 f.var = 10  
14 p f.var  
15 f.var = 10, 20  
11:06:18 [Temp]: ruby var.rb  
nil  
[]  
10  
[]

You can get it to work with send but then you’re loosing the clean  
syntax:

11:07:03 [Temp]: cat -n var.rb  
1  
2 class Foo  
3 def var=(val,\*opts)  
4 p opts  
5 @var = val  
6 end  
7  
8 def var() @var end  
9 end  
10  
11 f=Foo.new  
12 p f.var  
13 f.var = 10  
14 p f.var  
15 f.var = 10, 20  
16 p f.var  
17 f.send(:var=, 10, :opt =\> 20)  
11:08:08 [Temp]: ruby var.rb  
nil  
[]  
10  
[]  
[10, 20]  
[{:opt=\>20}]  
11:08:08 [Temp]:

Kind regards

```
robert
```
