Ross Bamford wrote: > On Sat, 2006-03-25 at 14:03 +0900, Eli Bendersky wrote: > > Eli Bendersky wrote: > > > Hello all, > > > > > > 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: > > > 1) 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] && ...'. > > > > 2) 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. > 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. Eli -- (http://eliben.blogspot.com)