I’m now writing my first real Ruby module, and on the second function I
already run into a pattern that seems to be very common.
I like using keyword arguments for methods, as follows:
def method(args)
…
end
And then call:
method(:arg1 => value1, :arg2 => value2)
And so on.
Now, often some arguments are compulsory, so I wrote the following code
to verify it:
def method(args)
[:username, :password, :url].each do |arg|
raise(ArgumentError, “Argument :#{arg} is compulsory” unless
args.has_key?(arg)
end
…
end
I have two questions:
Is this the right/idiomatic/best way to achieve what I’m attempting
?
Is there a library that encapsulates this capability, or is everyone
writing one of his own ? Because if I don’t find any, I surely will
write one… It should be enough saying:
raise(ArgumentError, "Argument :#{arg} is compulsory" unless
args.has_key?(arg)
end
…
end
I have two questions:
Is this the right/idiomatic/best way to achieve what I’m attempting
?
It works, and strikes me as more compact and elegant than a simple
‘raise unless args[:username] && args[:password] && …’.
Is there a library that encapsulates this capability, or is everyone
writing one of his own ? Because if I don’t find any, I surely will
write one… It should be enough saying:
verify_args(:username, :password, :url)
Instead of the .each do iteration everywhere
Not sure about libraries (though I’m sure they are out there, check RAA
and Rubyforge) but here’s a little trick I’ve used before:
args = { :one => ‘two’, :three => ‘four’ }
=> {:three=>“four”, :one=>“two”}
h = Hash.new { |h,k| raise ArgumentError, “#{k}” }.merge(args)
=> {:three=>“four”, :one=>“two”}
h[:one]
=> “two”
h[:three]
=> “four”
h[:two]
ArgumentError: two
from (irb):5
from (irb):11
This way, you never actually check the arguments explicitly, but you’ll
be told if your method uses one that wasn’t passed. Obviously for
optional arguments you go to the original hash.
h[:one]
This way, you never actually check the arguments explicitly, but you’ll
be told if your method uses one that wasn’t passed. Obviously for
optional arguments you go to the original hash.
This is a nice trick that can be used to handle optional keyword
variables with default values, and indeed it helps detect unwanted
variables.
I think it can be somehow combined with the method I presented - the
aim of which is to detect if any compulsory argument wasn’t passed in.
After all, there are arguments for which a default value is
meaningless.
This way, you never actually check the arguments explicitly, but you’ll
be told if your method uses one that wasn’t passed. Obviously for
optional arguments you go to the original hash.
What about using rescue for optional arguments? It might be slower though.
This way, you never actually check the arguments explicitly, but you’ll
be told if your method uses one that wasn’t passed. Obviously for
optional arguments you go to the original hash.
What about using rescue for optional arguments? It might be slower though.
What do you mean ? Can you provide an example ?
args = { :one => ‘two’, :three => ‘four’ }
=> {:three=>“four”, :one=>“two”}
h = Hash.new { |h,k| raise ArgumentError, “#{k}” }.merge(args)
=> {:three=>“four”, :one=>“two”}
h[:one]
=> “two”
h[:three]
=> “four”
v = h[:two] rescue “this string is the default for ‘two’”
p v
=> “this string is the default for ‘two’”
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.