Roger
Roger

Reputation: 3959

ruby alias_method question

I have following code

class User
  attr_accessor :name
end

u = User.new
u.name = 'john'
puts u.name #=> john

In the above case everything works. However this code does not work

class User
  attr_accessor :name
end

u = User.new
u.name = 'john'
u.name('john')

In order to fix that issue, I have decided to use alias_method. I know there are other ways to solve the problem, but I'm specifically looking if this problem could be solved using alias_method. Trying to learn.

Following code will work

class User
  attr_accessor :name
  alias_method :foo, :name=
end

u = User.new
u.foo('john')
puts u.name

However this code will not work for obvious reason.

class User
  attr_accessor :name
  alias_method :name, :name=
end

u = User.new
u.name('john')
puts u.name

Anyone knows if this problem can be fixed with alias_method.

Upvotes: 0

Views: 1624

Answers (4)

EmFi
EmFi

Reputation: 23450

The short version is alias method cannot help you here.

It looks like you're trying to merge the getter and setter created by attr_accessor. The reason this isn't working is because you're overriding the getter with the setter when you call alias.

To get the functionality you're looking for you'll have to define your own method.

Something like this:

class User
  attr_accessor :name

  def name(set_value = "VALUE_THAT_WILL_NEVER_BE_USED_AS_A_NAME")
    unless set_value == "VALUE_THAT_WILL_NEVER_BE_USED_AS_A_NAME"
      @name = set_value
    end
    @name
  end

end

u = User.new
u.name('john') #=> sets name to john
puts u.name #=> puts john

# bonus! doesn't override name=

u.name = 'mike' # => sets name to mike
puts u.name #=> puts mike

Edit: Corrected method to allow setting of nil or false.

Upvotes: 3

The Who
The Who

Reputation: 6622

If you want to use a single getter/setter method beware of using "nil" since you may want to set your attribute to nil.



u.name("john")
u.name(nil) # name still will be john

So do something which checks that there are args


class U
  attr_reader :n
  def n(*args)
    if(args.length > 0)
      @n = args.first
    else
      @n
    end
  end
end

u = U.new
u.n "j"
u.n # j
u.n nil
u.n # nil

Upvotes: 3

Rob Cameron
Rob Cameron

Reputation: 9776

class User
  attr_accessor :name
end

u = User.new
u.name = 'john'
u.name('john')

In this code u.name would be the getter for name. It looks like you're trying to call it as a setter? Is that want you want to do? If that's the case then you wouldn't use attr_accessor, you'd need to write the getters and setters yourself.

Upvotes: 1

Geo
Geo

Reputation: 96767

I don't really get what you're trying to do. By writing attr_acccessor :name, the name= method gets created automatically. If you're trying to make this work:

user.name("john")

you can add this method:

class User
   attr_accessor :name
   def name(n)
     self.name = n
   end
end

Upvotes: 4

Related Questions