2009-10-27 151 views
0

我有下面的代码红宝石alias_method问题

class User 
    attr_accessor :name 
end 

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

在上面的情况一切正常。但是,此代码不起作用

class User 
    attr_accessor :name 
end 

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

为了解决这个问题,我决定使用alias_method。我知道还有其他方法可以解决这个问题,但是我特别关注是否可以使用alias_method解决这个问题。试图学习。

下面的代码将工作

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

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

但是这个代码将不会很明显工作的原因所在。

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

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

任何人都知道这个问题是否可以用alias_method修复。

回答

3

简短的版本是别名方法不能帮助你在这里。

它看起来像你试图通过合并创建attr_accessor getter和setter。这不起作用的原因是因为你在调用别名时用setter重写getter。

为了得到你要找的功能,你必须定义自己的方法。

事情是这样的:

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 

编辑:纠正方法,以允许零或假的设置。

+0

不是如果unnessary? DEF名称(SET_VALUE) @name = SET_VALUE除非set_value.nil? 结束 – CodeJoust 2009-10-27 17:14:35

+0

我解释这个问题的方式,是指海报一直在寻找一种方式来获得,并用同样的方法设置。如果是必要的,但条件并不完美。因为它不会让nil或false分配给@name。 – EmFi 2009-10-27 17:19:37

4

我真的不明白你想做什么。通过写attr_acccessor :name,该name=方法被自动创建。如果你想使这项工作:

user.name("john") 

您可以添加这个方法:

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

你是不是写一个答案,也许这将是作为一个评论投注。 – johannes 2009-10-27 17:40:24

+0

有点难以添加所有这些作为评论,你不觉得吗? – Geo 2009-10-27 17:43:08

+0

正如我在我的问题说,我努力学习alias_method的阴暗面。我试图以特定的方式解决问题,但是我失败了。我想知道是否有人有我错过的解决方案。而已。只是学习。 – Roger 2009-10-28 03:32:10

1
class User 
    attr_accessor :name 
end 

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

在这段代码u.name将是name吸气。它看起来像你试图称它为二传手?那是你想要做的吗?如果是这种情况,那么你不会使用attr_accessor,你需要自己写getters和setters。

+0

我只是在玩alias_method,想要确定我无法实现的是不可能的。其次我得到了一些很好的答案。谢谢 – Roger 2009-10-28 03:35:36

3

如果您想使用单个getter/setter方法,请注意使用“nil”,因为您可能想将属性设置为nil。



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

所以做一些检查,有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