2009-10-27 2 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. Причина, по которой это не работает, заключается в том, что вы вызываете активатор при вызове псевдонима.

Чтобы получить функциональность, которую вы ищете, вам придется определить свой собственный метод.

Что-то вроде этого:

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: Исправленный метод, чтобы позволить установку нуля или ложным.

+0

Разве нет, если нет? def name (set_value) @name = set_value, если set_value.nil? end – CodeJoust

+0

То, как я интерпретировал этот вопрос, означает, что плакат искал способ получить и установить с помощью того же метода. Если это необходимо, но условие не является совершенным. Поскольку это не позволит нильскому или ложному присваивать @name. – EmFi

4

Я действительно не понимаю, что вы пытаетесь сделать. При написании attr_acccessor :name метод name= создается автоматически. Если вы пытаетесь сделать эту работу:

user.name("john") 

вы можете добавить этот метод:

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

Вы не пишете ответ, может быть, это было бы ставящий в качестве комментария. – johannes

+0

Kinda сложно добавить все это в качестве комментария, не так ли? – Geo

+0

Как я уже сказал в своем вопросе, я пытаюсь изучить темные стороны alias_method. Я попытался решить проблему определенным образом, и я потерпел неудачу. Мне было интересно, есть ли у кого-то решение, которое я пропустил. Вот и все. Только учится. – Roger

1
class User 
    attr_accessor :name 
end 

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

В этом коде u.name бы быть геттер для name. Похоже, вы пытаетесь назвать это сеттером? Хочешь ли ты этого сделать? Если это так, то вы не будете использовать attr_accessor, вам нужно будет написать геттеры и сеттеры самостоятельно.

+0

Я просто играл с alias_method и хотел быть уверенным, что то, чего я не могу достичь, невозможно. Во-вторых, я получил замечательные ответы. благодаря – Roger

3

Если вы хотите использовать один метод getter/setter, остерегайтесь использовать «nil», так как вы можете установить свой атрибут на nil.



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

Так что делать то, что проверяет, что есть арг


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 
Смежные вопросы