Tim Hunter
12/27/2006 8:03:00 PM
Nick Pavey wrote:
> Hi Folks,
>
> I'm porting an error reporting system from Perl to Ruby as a way of
> getting up the Ruby learning curve. Apologies in advance if my
> question has already been answered - I did a cursory search and got no
> hits.
>
> I'm running up against my lack of detailed Ruby knowledge, and I was
> wondering if someone could provide some advice - I'm sure that Ruby
> supports what I want to do.
>
> In the Perl world, I had a system where I could specify an error
> message and a set of parameters to that message, as follows:
>
> do_error(message, [parameters]);
>
> for example:
>
> do_error("param 1: '%s', param 2 : '%s', param 3 : '%s'",
> "detail1", "detail2", "detail3");
>
> would give the result:
>
> param 1: 'detail1', param 2 : 'detail2', param 3 : 'detail3'
>
> The perl implementation looks like this:
>
> sub do_error {
> my ($message, @params) = @_;
>
> printf($message, @params);
> }
>
> As you can see, the idea is that the user is able to specify both
> their error message and where in their message string various
> parameters appear.
>
> In this case, Perl was very obliging because parameter lists are
> simply arrays. Passing an array into printf became equivalent to
> passing the appropriate number of parameters.
>
> So, in Ruby, I have the following code:
>
> printf "#{@message}\n", @params
>
> Where class instance variable @params is an array. I have verified
> that it really is an array and not getting mangled somewhere in my
> class by using '@params.inspect'.
>
> Unfortunately, it seems that Ruby is treating the array in what Perl
> folks would call a "scalar context". The printf is getting a mangled
> version of the array contents and this is triggering a runtime error
> from Ruby.
>
> For example:
>
> @params = ["foo", "bar"]
> print @params.inspect
> >>> ["foo", "bar"]
>
> printf("%s %s", @params)
> >>> ErrorClasses.rb:32:in `printf': too few arguments (ArgumentError)
>
> I did some experiments, and it appears that printf is actually seeing:
> "foobar"
> instead of the array of 2 elements. If I have the right number of '%s'
> conversion codes in the format string, I get this message because Ruby
> thinks I've only passed on parameter, not many.
>
> For the record, here's the Ruby version I'm using
>
> BigWhite:nick> ruby -v
> ruby 1.8.4 (2005-12-24) [i686-darwin8.8.1]
>
>
> What would Ruby's code look like to achieve what I want?
>
> Thanks in advance,
>
>
> Nick
>
>
>
>
Welcome to Ruby!
Use the "*" (splat) operator to turn the array into a list of arguments.
printf "%s %s", *@params
The unary asterisk is often called the "unary unarray" operator because
it has this effect on an array.