Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > How can I get the arguments passed to the caller.

Reply
Thread Tools

How can I get the arguments passed to the caller.

 
 
Stefan Kanev
Guest
Posts: n/a
 
      01-25-2009
[Note: parts of this message were removed to make it a legal post.]

Hey guys.

I have a rather weird question. I want to write a function that
programatically determines the arguments passed to its caller. Say, if i do

$stuff = []

def bar(arg)
foo
end

def foo
first_arg = ....
$stuff << first_arg
end

bar(42)

# By this point, $stuff would be [42]

I know it is quite the contrived question, but I'm not interested in doing
something practical. Any leads?

 
Reply With Quote
 
 
 
 
Pascal J. Bourguignon
Guest
Posts: n/a
 
      01-25-2009
Stefan Kanev <(E-Mail Removed)> writes:

> [Note: parts of this message were removed to make it a legal post.]
>
> Hey guys.
>
> I have a rather weird question. I want to write a function that
> programatically determines the arguments passed to its caller. Say, if i do
>
> $stuff = []
>
> def bar(arg)
> foo
> end
>
> def foo
> first_arg = ....
> $stuff << first_arg
> end
>
> bar(42)


I don't think this is possible.


> # By this point, $stuff would be [42]

But to get this result you could write:

(def bar(*args)
($stuff = args)
end)

(bar 42)

$stuff --> [42]

> I know it is quite the contrived question, but I'm not interested in doing
> something practical. Any leads?



--
__Pascal Bourguignon__
 
Reply With Quote
 
 
 
 
James Coglan
Guest
Posts: n/a
 
      01-25-2009
[Note: parts of this message were removed to make it a legal post.]

> I have a rather weird question. I want to write a function that
> programatically determines the arguments passed to its caller. Say, if i do
>
> $stuff = []
>
> def bar(arg)
> foo
> end
>
> def foo
> first_arg = ....
> $stuff << first_arg
> end
>
> bar(42)
>
> # By this point, $stuff would be [42]




I think the closest you're going to get is for the calling function to pass
its binding so that foo can read from it:

def bar(*args)
foo(binding)
end
=> nil
def foo(env)
puts env.eval("args.first")
end
=> nil
bar 'something'
something

I don't think you can do this transparently. You can't even refer to the
argument list within a single method (I'm thinking of the 'arguments' object
in JavaScript) without mentioning the arguments by name.

 
Reply With Quote
 
Stefan Kanev
Guest
Posts: n/a
 
      01-25-2009
[Note: parts of this message were removed to make it a legal post.]

So, suppose I want to get evil and go dig into frames and so on. I've seen
ruby-debug do something close. Is there a part of the standard library that
allows you to introspect that way (if so, I could not find it), or a gem
maybe? And if not and I'm bend on writing C code to achieve it, where should
I start looking?

On Sun, Jan 25, 2009 at 9:39 PM, James Coglan <(E-Mail Removed)>wrote:

> > I have a rather weird question. I want to write a function that
> > programatically determines the arguments passed to its caller. Say, if i

> do
> >
> > $stuff = []
> >
> > def bar(arg)
> > foo
> > end
> >
> > def foo
> > first_arg = ....
> > $stuff << first_arg
> > end
> >
> > bar(42)
> >
> > # By this point, $stuff would be [42]

>
>
>
> I think the closest you're going to get is for the calling function to pass
> its binding so that foo can read from it:
>
> def bar(*args)
> foo(binding)
> end
> => nil
> def foo(env)
> puts env.eval("args.first")
> end
> => nil
> bar 'something'
> something
>
> I don't think you can do this transparently. You can't even refer to the
> argument list within a single method (I'm thinking of the 'arguments'
> object
> in JavaScript) without mentioning the arguments by name.
>


 
Reply With Quote
 
Robert Dober
Guest
Posts: n/a
 
      01-25-2009
On Sun, Jan 25, 2009 at 9:30 PM, Stefan Kanev <(E-Mail Removed)> wrote:
> So, suppose I want to get evil and go dig into frames and so on. I've seen
> ruby-debug do something close. Is there a part of the standard library that
> allows you to introspect that way (if so, I could not find it), or a gem
> maybe? And if not and I'm bend on writing C code to achieve it, where should
> I start looking?

Depends, for methods with *args and optional arguments you have
definitely some heavy lifting to do. For all other methods however
it's easy:
method( caller.first.sub(/.*in ./,"").sub(/.$/,"") ).arity
Probably not good enough?
cheers
Robert

 
Reply With Quote
 
Brian Candler
Guest
Posts: n/a
 
      01-26-2009
James Coglan wrote:
>> first_arg = ....
>> $stuff << first_arg
>> end
>>
>> bar(42)
>>
>> # By this point, $stuff would be [42]

>
>
>
> I think the closest you're going to get is for the calling function to
> pass
> its binding so that foo can read from it:


In which case, it might as well just pass its args instead

There is the Binding.of_caller hack which you can find through a google
search.

Maybe you could combine this with Kernel#local_variables or
Binding#local_variables to do what you want? That's what debug.rb does

when /^\s*l(?cal)?\s*$/
var_list(eval("local_variables", binding), binding)

and just use eval to read them:

def var_list(ary, binding)
ary.sort!
for v in ary
stdout.printf " %s => %s\n", v, eval(v, binding).inspect
end
end
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Stefan Kanev
Guest
Posts: n/a
 
      01-27-2009
[Note: parts of this message were removed to make it a legal post.]

Thanks for the advice. I would have never had thought of something as
straightforward as evaling 'local_variables' in the binding. Unfortunatelly,
I believe that this doesn't yield the arguments if they are not named.

I'm actually trying, out of curiosity, to implement a very straightforward
idea:

%w{more chunky bacon}.each { puts it.length }

Like, have *it* to actually be the 'implicit blog argument', not unlike
perl's $_. Again, I'm doing that out of curiosity. Any ideas how I can
accomplish it without touching the interpreter's C code?

On Mon, Jan 26, 2009 at 10:35 AM, Brian Candler <(E-Mail Removed)> wrote:

> James Coglan wrote:
> >> first_arg = ....
> >> $stuff << first_arg
> >> end
> >>
> >> bar(42)
> >>
> >> # By this point, $stuff would be [42]

> >
> >
> >
> > I think the closest you're going to get is for the calling function to
> > pass
> > its binding so that foo can read from it:

>
> In which case, it might as well just pass its args instead
>
> There is the Binding.of_caller hack which you can find through a google
> search.
>
> Maybe you could combine this with Kernel#local_variables or
> Binding#local_variables to do what you want? That's what debug.rb does
>
> when /^\s*l(?cal)?\s*$/
> var_list(eval("local_variables", binding), binding)
>
> and just use eval to read them:
>
> def var_list(ary, binding)
> ary.sort!
> for v in ary
> stdout.printf " %s => %s\n", v, eval(v, binding).inspect
> end
> end
> --
> Posted via http://www.ruby-forum.com/.
>
>


 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      01-27-2009
2009/1/27 Stefan Kanev <(E-Mail Removed)>:
> Thanks for the advice. I would have never had thought of something as
> straightforward as evaling 'local_variables' in the binding. Unfortunatelly,
> I believe that this doesn't yield the arguments if they are not named.
>
> I'm actually trying, out of curiosity, to implement a very straightforward
> idea:
>
> %w{more chunky bacon}.each { puts it.length }
>
> Like, have *it* to actually be the 'implicit blog argument', not unlike
> perl's $_. Again, I'm doing that out of curiosity. Any ideas how I can
> accomplish it without touching the interpreter's C code?


IMHO you can't because the current value is only known by method
#each. Wait, you could cook something up using thread local variables

18:41:58 tmp$ ./it.rb
4
6
5
18:42:41 tmp$ cat it.rb
#!/bin/env ruby

def it
Thread.current[:each].last rescue nil
end

class Array
alias _each each
def each(&b)
stack = Thread.current[:each] ||= []
_each do |val|
stack.push val
begin
b.call
ensure
stack.pop
end
end
end
end

%w{more chunky bacon}.each { puts it.length }
18:42:42 tmp$

But note that you have to change *all* implementations of #each which
is difficult to achieve because classes can spring into existence all
the time. Alternatively write a global each which receives the
Enumerable as argument.

Cheers

robert

--
remember.guy do |as, often| as.you_can - without end

 
Reply With Quote
 
Stefan Kanev
Guest
Posts: n/a
 
      01-29-2009
[Note: parts of this message were removed to make it a legal post.]

And I have to override Array#each. I'll also need to override #map, #select
and so on. Not a good deal

On Tue, Jan 27, 2009 at 7:46 PM, Robert Klemme
<(E-Mail Removed)>wrote:

> 2009/1/27 Stefan Kanev <(E-Mail Removed)>:
> > Thanks for the advice. I would have never had thought of something as
> > straightforward as evaling 'local_variables' in the binding.

> Unfortunatelly,
> > I believe that this doesn't yield the arguments if they are not named.
> >
> > I'm actually trying, out of curiosity, to implement a very

> straightforward
> > idea:
> >
> > %w{more chunky bacon}.each { puts it.length }
> >
> > Like, have *it* to actually be the 'implicit blog argument', not unlike
> > perl's $_. Again, I'm doing that out of curiosity. Any ideas how I can
> > accomplish it without touching the interpreter's C code?

>
> IMHO you can't because the current value is only known by method
> #each. Wait, you could cook something up using thread local variables
>
> 18:41:58 tmp$ ./it.rb
> 4
> 6
> 5
> 18:42:41 tmp$ cat it.rb
> #!/bin/env ruby
>
> def it
> Thread.current[:each].last rescue nil
> end
>
> class Array
> alias _each each
> def each(&b)
> stack = Thread.current[:each] ||= []
> _each do |val|
> stack.push val
> begin
> b.call
> ensure
> stack.pop
> end
> end
> end
> end
>
> %w{more chunky bacon}.each { puts it.length }
> 18:42:42 tmp$
>
> But note that you have to change *all* implementations of #each which
> is difficult to achieve because classes can spring into existence all
> the time. Alternatively write a global each which receives the
> Enumerable as argument.
>
> Cheers
>
> robert
>
> --
> remember.guy do |as, often| as.you_can - without end
>
>


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
to get values passed to a method as its arguments - how? Adam Wozniak Java 40 08-17-2009 10:13 AM
function default arguments from other arguments tutmann C++ 4 10-17-2006 08:00 PM
function call with arguments which takes no arguments Neo C Programming 10 01-20-2005 06:31 AM
Difference between default arguments and keyword arguments Edward Diener Python 14 04-05-2004 11:26 PM



Advertisments