1

I'd love to use a method signature like:

def register(something, on:, for:)

This works, but I can't work out how to use "for" without causing a syntax error! Rather annoying, anyone know a way around this?

3 Answers 3

3

The problem is not the method definition line that you posted, the problem is the usage of the for variable inside the method body. Since for is a reserved word, you cannot use it as a plain variable name, but you can use it as part of a hash. In your case that means you must resort to using arbitrary keyword arguments (**opts), but you can use the keyword_argument for: in the method call. You may want to raise an ArgumentError if the key is not present to emulate the behavior of the method signature you posted above.

def register(something, on:, **opts)
  raise ArgumentError, 'missing keyword: for' unless opts.has_key?(:for)
  for_value = opts[:for]

  puts "registering #{something} on #{on} for #{for_value}"
end

register 'chocolate chips', on: 'cookie'
# ArgumentError: missing keyword: for

register 'chocolate chips', on: 'cookie', for: 'cookie monster'
# registering chocolate chips on cookie for cookie monster
Sign up to request clarification or add additional context in comments.

3 Comments

This is one way :) I was hoping not to deviate from the named params format though
I know its not very pretty, but it gets the job done and the invocation syntax is just as clean
Yeah. I like this approach too, and is it really a deviation from the named params format if the method signature is still similar?
3
binding.local_variable_get(:for)

is a way I was thinking. Only works in ruby 2.1+ I think.

NOTE: Don't do this, I'm just interested in how you could get round it, you probably should just call your named parameter something else :)

Comments

2

In Ruby, for is a reserved keyword - looks like you just cannot use them in other way to how they were meant to use. That's the whole purpose of reserving keywords.

Additional resources on which keywords are reserved in Ruby:

UPD

Actualy, you can still use :for symbol as a key in hash (let's say, options hash), so, you can write like this:

def test(something, options = {})
  puts something
  puts options.values.join(' and ')
end 

and it works like charm:

[4] pry(main)> test 'arguments', :for => :lulz, :with => :care, :while => 'you are writing code' 
arguments
lulz and care and you are writing code

4 Comments

I know its a keyword, I mentioned that in the title. I asked if there was a way around it. some way to access it dynamically through the current binding or something?
@MichaelBaldry look into updated part - is it enough for you to use, or you meant some other way? BTW, in my humble opinion, usage of keywords in such manner can increase amount of "WTF?!" per line. ;)
Both links don't mention __ENCODING__. Also, since 2.2.0 Ruby comes with an official document: $ ri ruby:keywords.
I know it adds to the WTF/L, I'm just curious :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.