[comp.sys.next] methods with arbitrary # of args? How?

pbiron@weber.ucsd.edu (Paul Biron) (10/16/90)

Is it possible to define an obj-c method which takes an
arbitrary number of arguments (ala normal C functions
which use varargs.h)?

If so, how?  If not, does anybody have an "elegent" way
to simulate this kind of behavior?

Any advice would be appreciated.

Paul Biron      pbiron@ucsd.edu        (619) 534-5758
Central University Library, Mail Code C-075-R
Social Sciences DataBase Project
University of California, San Diego, La Jolla, Ca. 92093

lane@SUMEX-AIM.STANFORD.EDU (Christopher Lane) (10/16/90)

In <3860@network.ucsd.edu>, pbiron@weber.ucsd.edu writes:
>Is it possible to define an obj-c method which takes an arbitrary
>number of arguments (ala normal C functions which use varargs.h)?

#import <stdarg.h> /* actually imported by Object.h file anyway */
#import <objc/Object.h>

@interface MyObject : Object { }

- myMethod:arg1, ...;

@end

@implementation MyObject

- myMethod:arg1, ...
{
	va_list	ap;

	va_start(ap, arg1);
	/* f = va_arg(ap, type); */
	va_end(ap);

	return self;
}

@end

To be able to figure out the number of arguments actually given at runtime,
you have to either include that information in the value of 'arg1', pass and
test for an explicit NULL at the end of the list of arguments or pass off the
whole lot to something else that handles multiple arguments (e.g vsprintf).

- Christopher
-------

lerman@stpstn.UUCP (Ken Lerman) (10/16/90)

In article <3860@network.ucsd.edu> pbiron@weber.ucsd.edu (Paul Biron) writes:
>Is it possible to define an obj-c method which takes an
>arbitrary number of arguments (ala normal C functions
>which use varargs.h)?
[...]
>Paul Biron      pbiron@ucsd.edu        (619) 534-5758
>Central University Library, Mail Code C-075-R
>Social Sciences DataBase Project
>University of California, San Diego, La Jolla, Ca. 92093

This is done in (more or less) the same manner as in plain old C (K&R):

#include <varargs.h>
+ with: (unsigned) nArgs, ...
{
    va_list vp;
    va_start(vp);
    while (nArgs-- > 0)
    {
        int arg = va_arg(vp,int);
    }
    va_end(vp);
    return self;
}

or, in ANSI C:

#include <stdarg.h>
+ with: (unsigned) nArgs, ...
{
    va_list vp;
    va_start(vp,nArgs);
    while (nArgs-- > 0)
    {
        int arg = va_arg(vp,int);
    }
    va_end(vp);
    return self;
}

depending on whether your Objective-C compiler is targeted for ANSI or K&R.

Your interface file should include the line:
+ with: (unsigned) nArgs, ...;

Note that the next Stepstone release of Objective-C will use the macro
VA_START(v,n) which will work for either of the above environments.
Also, there is no need to include either of the above files if you
include Object.h (because it will include the proper file).

In this matter, I speak for myself, not for Stepstone.

Ken

moose@svc.portal.com (10/16/90)

In article <3860@network.ucsd.edu> pbiron@weber.ucsd.edu (Paul Biron) writes:
>Is it possible to define an obj-c method which takes an
>arbitrary number of arguments (ala normal C functions
>which use varargs.h)?
>
>If so, how?  If not, does anybody have an "elegent" way
>to simulate this kind of behavior?

Everything is possible and elegant is relative.

Try this:

- myMethod:(int) argc :(char **)argv;

When you call it, malloc out an array of pointers for argv, then malloc out
each sub pointer, then, voila, you have an arbitrary number of arguments.
If your argv is small, and/or your entire data is small, you might want to
use alloca instead of malloc.  alloca does not need corresponding calls to free.

Similarly
- myMethod:(char *)pattern :(void *)data;

lets you do something along the line of printf.
Matter of fact, using sprintf, you can fill the data with your arguments
relatively easilty.

-- 
Michael Rutman				|	moose@svc.portal.com
Cubist					|	makes me a NeXT programmer
Software Ventures			|	That's in Berkeley
smile, you're on standard disclaimer	|	<fill in with cute saying>

pbiron@weber.ucsd.edu (Paul Biron) (10/17/90)

In <3860@network.ucsd.edu>, pbiron@weber.ucsd.edu (Paul Biron) writes:

	>Is it possible to define an obj-c method which takes an
	>arbitrary number of arguments (ala normal C functions
	>which use varargs.h)?

The net comes through again, thanx to those who responded!!!

The "answer" is, (from NeXT manuals, Chap 3, p 12):

	Methods that take a varaible number of arguments declare them
	just as a function would.

	- makeGroup:group,... ;

That's it!  No mention of how to call them though!!!!  However,
in Chap 22, p 31 (the Spec sheet for Object), there's an example
call of Objects error: method which is a vararg method (sorry,
I forgot to write down the call, but it went something like this):

	- error:(STR)str,... ;

	[self error:"index %d is greater than max %d\n", index, max] ;

IOW, the _method_ only has 1 argument, but that 1 argument is made
up of comma separated "arguments".

Note that the same kinds of restrictions that apply to the use
of varargs.h, apply here.

I have also been told there is an example of this in Issue 9 of
the _NeXT User's Journal_, in the Buzz Hints section.

Thanx again to those who pointed me in the right direction!

Paul Biron      pbiron@ucsd.edu        (619) 534-5758
Central University Library, Mail Code C-075-R
Social Sciences DataBase Project
University of California, San Diego, La Jolla, Ca. 92093

kenneth@EB.se (Kenneth Persson) (10/19/90)

Look for the file mivarargs.h and for examples
look at the |error:| method in the class Object:

//
//  Generate an error diagnostic using aCStr in the style of  printf
//  followed by a variable number of argument, e.g.:
//
//      return [self error:"index %d exceeds limit %d", index, limit];
//
- error: (STR) aCStr, ...
{
        va_list ap;
        va_start(ap);
        return (*_error)(self, aCStr, ap);
        va_end(ap);
}

or at the |sprintf:| method in the class String:

//
//      Create a new instance and assign string
//      from the format and args.
//
+ sprintf:(STR)fmt, ...
{
    char buf[BUFSIZ];
    va_list ap;
    va_start(ap);
    vsprintf(buf, fmt, ap);
    va_end(ap);
    return [self str: buf];
}

p.s Can somebody out there reply to me if this message has reached you?
    I'm not sure our postings are spread.



--
      +-------------------------+--------------------------+
      |  Kenneth Persson        |  email: kenneth@eb.se    |
      |  EB Signal AB, Sweden   |  voice: +46 8 726 2267   |
      +-------------------------+--------------------------+