2015-06-01 2 views
2

Можно ли получить доступ к аргументам ключевого слова для хеша, используя новый синтаксис ruby ​​2.0?Рубиновое ключевое слово как именованный хеш-параметр

class List::Node 
    attr_accessor :data, :next 
    def initialize data: nil, next: nil 
    self.data = data 
    self.next = next # ERROR! 
    end 
end 

Старый синтаксис работает отлично:

class List::Node 
    attr_accessor :data, :next 
    def initialize options = { data: nil, next: nil } 
    self.data = options[:data] 
    self.next = options[:next] 
    end 
end 

----- EDIT -----

Я понимаю, что next является зарезервированным словом, но я предполагаю, что атрибуты ключевого слова сохраняются внутренне в хеше, и мне интересно, можно ли получить к нему доступ, например с помощью self.args, self.parameters, self.options и т.д.

ответ

3

Это будет работать:

class List::Node 
    attr_accessor :data, :next 
    def initialize data: nil, _next: nil 
    self.data = data 
    self.next = _next 
    end 
end 

next Руби зарезервированное слово. Используйте имена, которые не являются зарезервированным ключевым словом Ruby.

EDIT: Да, возможно, но это не очень хорошая идея.

class List::Node 
    attr_accessor :data, :next 
    def initialize data: nil, next: nil 
    self.data = data 
    self.next = binding.local_variable_get(:next) 
    end 
end 
p List::Node.new.next # nil 

Посмотрите local_variable_get.

+0

Это именно то, что я искал, спасибо! Я никогда не ставил этот код на производство, но я играю с рубином, пытаясь понять его лучше. – makhan

0

Ошибка в том, что ключевое слово next рубин. Выберите другое имя, и все должно быть хорошо.

1

Так же, как *args собирает все позиционные параметры, не упоминания в списке аргументов, **kwargs собирает все именованные аргументы вы не упоминания в списке аргументов. Насколько мне известно, нет никакого неаккуратного способа доступа к позиционному параметру как от объявленного параметра, так и от знака в одно и то же время, а также для аргументов ключевого слова.

def foo(pos1, pos2, *args, reqkw:, optkw: nil, **kwargs) 
    puts [pos1, pos2, reqkw, optkw, args, kwargs].inspect 
end 
foo(1, 2, 8, reqkw: 3, optkw: 4, extkw: 9) 
# => [1, 2, 3, 4, [8], {:extkw=>9}] 

I.e. вы можете получить доступ к 1, 2 только в качестве позиционных аргументов и 8 только из знака; Таким же образом вы можете получить доступ к 3 и 4 только из аргументов ключевого слова и 9 только из doublelesplat.

(Arup Ракшит уже дает Hacky способ доступа к параметрам символом. - но обратите внимание, что это имеет доступ ко всем локальным переменным, а не только параметры)

Смежные вопросы