Forum: Ruby Method missing and arrays as arguments..

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
9dec3df8319c613f6f4f14a27da0fdb4?d=identicon&s=25 Kyle Schmitt (Guest)
on 2009-04-06 22:36
(Received via mailing list)
How do you go about passing arrays as arguments to something like
method_missing?  I've got a method that takes an array as an argument,
but calling it via method_missing is proving problematic.  How do you
deal with arrays in these situations?

  def table_row(values)
    # values is the list of items in the table row
    #....
  end

  def method_missing(method,*args)
    if respond_to?method.to_s[/^add_([^$]+)/,1]
        @data<<method(method.to_s[/^add_([^$]+)/,1]).call(*args)
    else
      super method_missing(method,*args)
    end
  end


--Kyle
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 Gary Wright (Guest)
on 2009-04-06 23:02
(Received via mailing list)
On Apr 6, 2009, at 4:35 PM, Kyle Schmitt wrote:

>    end
>  end


I think your problem is in the else clause.  It should be:

    else
  super
    end

You don't want to call method_missing explicitly, you'll create an
infinite recursion.
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2009-04-06 23:14
(Received via mailing list)
On Mon, Apr 6, 2009 at 4:35 PM, Kyle Schmitt <kyleaschmitt@gmail.com>
wrote:

>  def method_missing(method,*args)
>    if respond_to?method.to_s[/^add_([^$]+)/,1]
>        @data<<method(method.to_s[/^add_([^$]+)/,1]).call(*args)
>    else
>      super method_missing(method,*args)
>    end
>  end



I'm not sure exactly what you are trying to do, I'm guessing that if you
send add_table_row(some_array) to an instance, the method_missing will
call
table_row and add the result to @data.

The problem isn't the array argument, it's what you are doing in the
true
leg of the if.

The first argument to method_missing is not a method, but a symbol.  You
are
converting this symbol to a string, stripping off add_ from the
beginning
and they trying to call the string, which ain't gonna work.

Instead you want to use send:

class SomeClass
  attr_reader :data

  def table_row(values)
    # values is the list of items in the table row
    #....
    values
  end

  def method_missing(symbol,*args)
    without_add = symbol.to_s[/^add_([^$]+)/,1]
    if respond_to? without_add
        @data ||= []
        @data<< send(without_add, *args)
    else
      super method_missing(method,*args)
    end
  end
end

sc = SomeClass.new
sc.add_table_row([1,2,3])
sc.data # => [[1, 2, 3]]

I used lazy initialization to initialize @data, assuming that this is
vaguely what you are after.

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2009-04-06 23:15
(Received via mailing list)
On Mon, Apr 6, 2009 at 5:00 PM, Gary Wright <gwtmp01@mac.com> wrote:

>>       @data<<method(method.to_s[/^add_([^$]+)/,1]).call(*args)
>        super
>   end
>
> You don't want to call method_missing explicitly, you'll create an infinite
> recursion.
>
>
Well, that's another problem, which I overlooked in MY response.

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
9dec3df8319c613f6f4f14a27da0fdb4?d=identicon&s=25 Kyle Schmitt (Guest)
on 2009-04-07 00:06
(Received via mailing list)
Ok, I found my issue, it was rather dense of me to be honest, it had
to do with how I was calling it.

That said, this is what I came up with


  def method_missing(method,*args)
    without_add=method.to_s[/^add_([^$]+)/,1]
    if not(without_add.empty?) and respond_to?without_add
        #calling the string worked (I'm guessing it tries a .to_sym)
        #@data<<method(without_add).call(*args)
        # Still, this is prettier
        @data<<send(without_add,*args)
    else
      super
    end
  end
9dec3df8319c613f6f4f14a27da0fdb4?d=identicon&s=25 Kyle Schmitt (Guest)
on 2009-04-07 19:39
(Received via mailing list)
Oh, and I forgot to say, thanks, it did help a ton.
This topic is locked and can not be replied to.