Re: Calling through a function reference with a variable argument list

2006-06-13 Thread Bob Hiestand

On 6/12/06, Hari Krishna Dara [EMAIL PROTECTED] wrote:


On Mon, 12 Jun 2006 at 4:07pm, Charles E Campbell Jr wrote:

 Bob Hiestand wrote:

  On 6/2/06, Charles E Campbell Jr [EMAIL PROTECTED] wrote:
 
  Bob Hiestand wrote:
 
My question is whether there is a simpler way to pass an unknown
   number of arguments from the current function to a function which
   accepts a variable-length list of arguments.
 
  ...snip...


  I don't think that does what I wanted, though I may have misunderstood
  the implications.  That converts the arguments into a string
  representation of a list, which then becomes the single argument to
  the second function.

 Looks like I made a mistake.  Here's one that does illustrate passing a
 variable number of arguments along:

  --
 fun! AFunc(...)
   let args = string(a:000)
   let len  = strlen(args)
   let args = strpart(args,1,len-2)
   echomsg call BFunc(.args.) a:0=.a:0
   exe call BFunc(.args.)
 endfun

  --
 fun! BFunc(...)
   echomsg BFunc sees: a:0=.a:0
   echomsg a:000.string(a:000).
 endfun

  --
 echomsg 'AFunc(1):'
 call AFunc(1)

 echomsg 'AFunc(1,a):'
 call AFunc(1,a)

 echomsg 'AFunc(1,a,b):'
 let b=BBB
 call AFunc(1,a,b)

 The idea is to have a string hold just the arguments, not the list
 delimiters.
 The exe squeezes the string together and then executes it.  Consequently,
 the output is:

 AFunc(1):
 call BFunc(1) a:0=1
 BFunc sees: a:0=1
 a:000[1]
 AFunc(1,a):
 call BFunc(1, 'a') a:0=2
 BFunc sees: a:0=2
 a:000[1, 'a']
 AFunc(1,a,b):
 call BFunc(1, 'a', 'BBB') a:0=3
 BFunc sees: a:0=3
 a:000[1, 'a', 'BBB']
 P

 So you can see that BFunc is being called with a variable number of
 arguments depending on whatever AFunc received (look at the
 BFunc sees: lines)

I don't know if the OP can use a Vim7.0 only solution, but the genutils
plugin has a utility to make this possible for prior versions. I have
been using this in several places of one of my plugins with no issues.
However, if Vim7.0 only solution is acceptable, Vim supports this
already with the call() function.

 --
fun! AFunc(...)
  echomsg call BFunc(.string(a:000).) a:0=.a:0
  call call('BFunc', a:000)
endfun

 --
fun! BFunc(...)
  echomsg BFunc sees: a:0=.a:0
  echomsg a:000.string(a:000).
endfun

--
HTH,
Hari


 
  My intention was to create a passthrough function that could call any
  other function after determining the function to which it would
  dispatch control (the application here is a general source integration
  script that would dispatch to the appropriate function specific to the
  version control system controlling the current file).
 
  As it turns out, I was a victim of narrow thinking because I was
  trying to modify as little as possible of an existing plugin.  The
  correct change was to simply make the dispatch function and the  end
  functions accept a list as the parameter, in which case pass-through
  becomes trivial.
 
  Thank you for looking at this,

 You're welcome!
 Chip Campbell


Thanks, Hari, that was exactly the functionality I wanted.


Re: Calling through a function reference with a variable argument list

2006-06-12 Thread Hari Krishna Dara

On Mon, 12 Jun 2006 at 4:07pm, Charles E Campbell Jr wrote:

 Bob Hiestand wrote:

  On 6/2/06, Charles E Campbell Jr [EMAIL PROTECTED] wrote:
 
  Bob Hiestand wrote:
 
My question is whether there is a simpler way to pass an unknown
   number of arguments from the current function to a function which
   accepts a variable-length list of arguments.
 
  ...snip...


  I don't think that does what I wanted, though I may have misunderstood
  the implications.  That converts the arguments into a string
  representation of a list, which then becomes the single argument to
  the second function.

 Looks like I made a mistake.  Here's one that does illustrate passing a
 variable number of arguments along:

  --
 fun! AFunc(...)
   let args = string(a:000)
   let len  = strlen(args)
   let args = strpart(args,1,len-2)
   echomsg call BFunc(.args.) a:0=.a:0
   exe call BFunc(.args.)
 endfun

  --
 fun! BFunc(...)
   echomsg BFunc sees: a:0=.a:0
   echomsg a:000.string(a:000).
 endfun

  --
 echomsg 'AFunc(1):'
 call AFunc(1)

 echomsg 'AFunc(1,a):'
 call AFunc(1,a)

 echomsg 'AFunc(1,a,b):'
 let b=BBB
 call AFunc(1,a,b)

 The idea is to have a string hold just the arguments, not the list
 delimiters.
 The exe squeezes the string together and then executes it.  Consequently,
 the output is:

 AFunc(1):
 call BFunc(1) a:0=1
 BFunc sees: a:0=1
 a:000[1]
 AFunc(1,a):
 call BFunc(1, 'a') a:0=2
 BFunc sees: a:0=2
 a:000[1, 'a']
 AFunc(1,a,b):
 call BFunc(1, 'a', 'BBB') a:0=3
 BFunc sees: a:0=3
 a:000[1, 'a', 'BBB']
 P

 So you can see that BFunc is being called with a variable number of
 arguments depending on whatever AFunc received (look at the
 BFunc sees: lines)

I don't know if the OP can use a Vim7.0 only solution, but the genutils
plugin has a utility to make this possible for prior versions. I have
been using this in several places of one of my plugins with no issues.
However, if Vim7.0 only solution is acceptable, Vim supports this
already with the call() function.

 --
fun! AFunc(...)
  echomsg call BFunc(.string(a:000).) a:0=.a:0
  call call('BFunc', a:000)
endfun

 --
fun! BFunc(...)
  echomsg BFunc sees: a:0=.a:0
  echomsg a:000.string(a:000).
endfun

-- 
HTH,
Hari


 
  My intention was to create a passthrough function that could call any
  other function after determining the function to which it would
  dispatch control (the application here is a general source integration
  script that would dispatch to the appropriate function specific to the
  version control system controlling the current file).
 
  As it turns out, I was a victim of narrow thinking because I was
  trying to modify as little as possible of an existing plugin.  The
  correct change was to simply make the dispatch function and the  end
  functions accept a list as the parameter, in which case pass-through
  becomes trivial.
 
  Thank you for looking at this,

 You're welcome!
 Chip Campbell

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 


Re: Calling through a function reference with a variable argument list

2006-05-17 Thread Bob Hiestand

On 5/16/06, Hari Krishna Dara [EMAIL PROTECTED] wrote:


On Tue, 16 May 2006 at 2:43pm, Bob Hiestand wrote:

 Hi all,

   I'm re-writing my cvscommand.vim plugin to handle both CVS and
 Subversion version control systems.  I'm currently implementing some
 of the functionality through function references that define common
 operations for each source control system in a dictionary specfic to
 that system.  I have a situation where I have a generic dispatch
 function that identifies which dictionary to dereference to obtain the
 function reference.

   The problem is that the function eventually called behind the
 function reference may have any number of arguments.  Therefore, the
 dispatch function takes any number of arguments to pass through.  This
 leads to the actual call, which looks like this (all on one line):

 function! s:ExecuteVCSCommand(command, ...)
find the proper functionMap dictionary, and then:
   execute return functionMap[a:command]( . join(map(copy(a:000),
 '\' . v:val . '\'), ,) . )

   My question is whether there is a simpler way to pass an unknown
 number of arguments from the current function to a function which
 accepts a variable-length list of arguments.

 Thank you,

 Bob

My suggestion would be to have the underlying methods always accept a
list of arguments, then you can just pass a:000 straight-through.


Yes, I've changed the implementation functions in this way per Yakov.  Thanks.


BTW, your approach to enclose the arguments in double-quotes is a
bad-idea, especially if you are handling paths on windows with
back-slashes in them (among various others). Imagine what would happen
if the argument is c:\dev\tst\newfile, both \t and \n will result
in getting expanded to tab and newline. What you should do is to use
single-quotes to avoid accidental transformations, but then escape the
existing single-quotes themselves (if any). Take a look at the
MakeArgumentString() function in my genutils.vim.

--
HTH,
Hari


Yes, I've changed the implementation functions in this way per Yakov.  Thanks.

With your heads-up about the double quote in mind, I'm glad that I'm
not using execute now, as the equivalent expression looks to be:

execute 'return functionMap[a:command](' . join(map(copy(b:alist),
' . v:val . ')), ',') . ')'

which is fairly difficult for me to read.

Thank you,

Bob


Calling through a function reference with a variable argument list

2006-05-16 Thread Bob Hiestand

Hi all,

 I'm re-writing my cvscommand.vim plugin to handle both CVS and
Subversion version control systems.  I'm currently implementing some
of the functionality through function references that define common
operations for each source control system in a dictionary specfic to
that system.  I have a situation where I have a generic dispatch
function that identifies which dictionary to dereference to obtain the
function reference.

 The problem is that the function eventually called behind the
function reference may have any number of arguments.  Therefore, the
dispatch function takes any number of arguments to pass through.  This
leads to the actual call, which looks like this (all on one line):

function! s:ExecuteVCSCommand(command, ...)
  find the proper functionMap dictionary, and then:
 execute return functionMap[a:command]( . join(map(copy(a:000),
'\' . v:val . '\'), ,) . )

 My question is whether there is a simpler way to pass an unknown
number of arguments from the current function to a function which
accepts a variable-length list of arguments.

Thank you,

Bob


Re: Calling through a function reference with a variable argument list

2006-05-16 Thread Yakov Lerner

On 5/16/06, Bob Hiestand [EMAIL PROTECTED] wrote:

 I'm re-writing my cvscommand.vim plugin to handle both CVS and
Subversion version control systems.  I'm currently implementing some
of the functionality through function references that define common
operations for each source control system in a dictionary specfic to
that system.  I have a situation where I have a generic dispatch
function that identifies which dictionary to dereference to obtain the
function reference.

 The problem is that the function eventually called behind the
function reference may have any number of arguments.  Therefore, the
dispatch function takes any number of arguments to pass through.  This
leads to the actual call, which looks like this (all on one line):

function! s:ExecuteVCSCommand(command, ...)
  find the proper functionMap dictionary, and then:
 execute return functionMap[a:command]( . join(map(copy(a:000),
'\' . v:val . '\'), ,) . )

 My question is whether there is a simpler way to pass an unknown
number of arguments from the current function to a function which
accepts a variable-length list of arguments.


The only thing I can think of is rewriting target functions
into accepting 1 argument which is a list. I don't find
vim vararg mechanism easy to use in general.

Yakov