Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a setter method that takes extra arguments in Ruby

I'm trying to write a method that acts as a setter and takes some extra arguments besides the assigned value. Silly example:

class WordGenerator
  def []=(letter, position, allowed)
    puts "#{letter}#{allowed ? ' now' : ' no longer'} allowed at #{position}"
  end

  def allow=(letter, position, allowed)
    # ...
  end
end

Writing it as an indexer works and I can call it like this:

gen = WordGenerator.new

gen['a', 1] = true
# or explicitly:
gen.[]=('a', 1, true)

But when I try any of the following, the interpreter complains:

gen.allow('a', 1) = false # syntax error
gen.allow=('a', 1, false) # syntax error

Why won't this work, am I missing the obvious?

like image 611
Valentin Milea Avatar asked Mar 04 '10 16:03

Valentin Milea


People also ask

How do you use the setter method in Ruby?

these methods allow us to access a class's instance variable from outside the class. Getter methods are used to get the value of an instance variable while the setter methods are used to set the value of an instance variable of some class.

What helper can you use to create a getter and setter Ruby?

Accessors are a way to create getter and setter methods without explicitly defining them in a class. There are three types fo accessors in Ruby. attr_reader automatically generates a getter method for each given attribute. attr_writer automatically generates a setter method for each given attribute.

What is * args Ruby?

In the code you posted, *args simply indicates that the method accepts a variable number of arguments in an array called args . It could have been called anything you want (following the Ruby naming rules, of course).


1 Answers

It doesn't work because the parser doesn't allow it. An equals sign is allowed in expressions of the form identifier = expression, expression.identifier = expression (where identifier is \w+), expression[arguments] = expression and expression.[]= arguments and as part of a string or symbol or character literal (?=). That's it.

gen.send(:allow=, 'a', 1, false) would work, but at that point you could as well just give the method a name that doesn't include a =.

like image 126
sepp2k Avatar answered Nov 03 '22 01:11

sepp2k