Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby keyword as named hash parameter

Tags:

ruby

ruby-2.0

Is it possible to access the hash holding keyword arguments using the new ruby 2.0 syntax?

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

Old syntax works fine:

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 -----

I realize next is a reserved word but I'm guessing keyword attributes are stored internally in a hash and I'm wondering whether it's possible to access it, e.g. via self.args, self.parameters, self.options, etc.

like image 989
makhan Avatar asked Jun 01 '15 08:06

makhan


2 Answers

This will work:

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

next is Ruby reserved word. Use names which are not Ruby's reserved keyword.

EDIT: Yes, possible, but not a good idea.

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

Look local_variable_get .

like image 190
Arup Rakshit Avatar answered Sep 22 '22 14:09

Arup Rakshit


Just like *args collects all the positional parameters you didn't mention in the argument list, **kwargs collects all the keyword arguments you didn't mention in the argument list. As far as I know, there is no non-hacky way to access a positional parameter both from a declared parameter and a splat at the same time, and the same goes for keyword arguments.

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. you can access 1, 2 only as positional arguments, and 8 only from the splat; in the same way, you can access 3 and 4 only from the keyword arguments, and 9 only from the doublesplat.

(Arup Rakshit already gives the hacky way to access parameters by symbol - but note that this accesses all local variables, not only parameters.)

like image 26
Amadan Avatar answered Sep 19 '22 14:09

Amadan