Avoiding interpret?

  • Follow


I'm trying to write a subroutine which will in turn call a function,
using EXACTLY the same number of arguments as it received. I'll
explain why later.

I can achieve this with:

Select
  When arg() = 0 then say func()
  When arg() = 1 then say func(arg(1))
  When arg() = 2 then say func(arg(1),arg(2))
  ...
  Otherwise say 'Too many arguments'
  End

.... but I could conceivably need to handle in excess of 100 arguments,
so the code would look silly. I can get around this with Interpret.
Can anyone suggest anything more elegant?

The reason is simple: the function is in an external package over
which I have no control. The number of arguments that you have to
supply is one for each "?" in the first argument. If you supply the
wrong number of arguments (as defined in arg(1)) then you get a syntax
error.

Incidentally, I wondered what the upper limit on the number of
arguments is. I found it to be 255. If you pass more than 255, then
arg() returns the actual number modulo 256. At least, in my IBM Object
Rexx it does. This seems like a bug, but since this is the first time
I've encountered it in 30 years, I'm not going to worry about it. A
problem shared is a problem doubled, so maybe someone else can worry
about it for me.

-- 
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
0
Reply Swifty 7/28/2010 7:18:25 AM

On Wed, 28 Jul 2010 08:18:25 +0100, Swifty wrote:
>Can anyone suggest anything more elegant?

I doubt it.  Just be glad you don't need to check ARG(i,'E') for each
argument and construct 2**100 WHEN clauses instead of just 100.

�R - we don't have branes made of clockworks, chocolate maidens
http://users.bestweb.net/~notr/arkville.html    --the Ur-beatle
0
Reply Glenn 7/28/2010 12:42:37 PM


 > I can get around this with Interpret. Can anyone suggest anything
 > more elegant?
 
INTERPRET in the Rexx toolbox as such can be elegant, but its use can
always be avoided. Which may be an unelegant, lengthy PITA.

 > the function is in an external package over which I have no control.
 
Too bad. The external package is sloppy code. With a ridiculous number
of arguments in use, its author should have used the RexxVariablePool,
or something like that, assuming the external package is written for
use with Rexx. Bad design. Or perhaps bad use, stretching its limits
too far. You don't have to call SysStemSort by mentioning each stem
item individually, right?

 > Incidentally, I wondered what the upper limit on the number of
 > arguments is.
 
That also depends on the length of the commandline, a.o. Exceed that
limit with one argument, and the limit is 0. Would it be well-designed
if you have to enter 257 serious arguments, without any typo's?! That
may be abuse of a toolbox-item (arguments) too, even if it works. 



---
0
Reply spamgate 7/28/2010 3:06:17 PM

Glenn Knickerbocker wrote:
> On Wed, 28 Jul 2010 08:18:25 +0100, Swifty wrote:
>> Can anyone suggest anything more elegant?
> 
> I doubt it.  Just be glad you don't need to check ARG(i,'E') for each
> argument and construct 2**100 WHEN clauses instead of just 100.
> 
> �R - we don't have branes made of clockworks, chocolate maidens
> http://users.bestweb.net/~notr/arkville.html    --the Ur-beatle

Well if you did, then this snippet of code from a member of RexxLA.org would help:

say "Need to check the args now"
signal Good_Args
args_return:
say "The args have now been checked"
return

Good_Args:
  parse value sourceline(sigl+1) with _returnlabel ':' .
  do _a=1 to arg()
     if \arg(_a,'E') then _error._a=1
  end
  /* and so on */
  signal value _returnlabel

-- 

Les               (Change Arabic to Roman to email me)
0
Reply LesK 7/28/2010 4:22:28 PM

On 07/28/2010 12:22 PM, LesK wrote:
> Good_Args:
>  parse value sourceline(sigl+1) with _returnlabel ':' .
>  do _a=1 to arg()
>     if \arg(_a,'E') then _error._a=1
>  end
>  /* and so on */
>  signal value _returnlabel

I'm not sure how the SIGNAL part of this is supposed to help.  Yes,
calling ARG(,'E') only once per argument makes sense, but the brute
force part I'm talking about is the 2**n cases you need *after* doing that:

e. = 0
Do i = 1 to Arg()
  a.i = Arg(i)       /* (this is just to shorten the code below) */
  e.i = Arg(i, 'E')  /* (this saves time by calling only once) */
End
Select
  When \e.1 & \e.2 & \e.3 then Return func()
  When  e.1 & \e.2 & \e.3 then Return func(a.1)
  When \e.1 &  e.2 & \e.3 then Return func(, a.2)
  When  e.1 &  e.2 & \e.3 then Return func(a.1, a.2)
  When \e.1 & \e.2 &  e.3 then Return func(, , a.3)
  When  e.1 & \e.2 &  e.3 then Return func(a.1, , a.3)
  When \e.1 &  e.2 &  e.3 then Return func(, a.2, a.3)
  Otherwise                    Return func(a.1, a.2, a.3)
End

Now imagine constructing something like that for 100 arguments.  Your
routine would run into the millions of hellabytes.

�R
0
Reply Glenn 7/28/2010 10:46:30 PM

Glenn Knickerbocker wrote:
> On 07/28/2010 12:22 PM, LesK wrote:
>> Good_Args:
>>  parse value sourceline(sigl+1) with _returnlabel ':' .
>>  do _a=1 to arg()
>>     if \arg(_a,'E') then _error._a=1
>>  end
>>  /* and so on */
>>  signal value _returnlabel
> 
> I'm not sure how the SIGNAL part of this is supposed to help.  Yes,
> calling ARG(,'E') only once per argument makes sense, but the brute
> force part I'm talking about is the 2**n cases you need *after* doing that:
> 
> e. = 0
> Do i = 1 to Arg()
>   a.i = Arg(i)       /* (this is just to shorten the code below) */
>   e.i = Arg(i, 'E')  /* (this saves time by calling only once) */
> End
> Select
>   When \e.1 & \e.2 & \e.3 then Return func()
>   When  e.1 & \e.2 & \e.3 then Return func(a.1)
>   When \e.1 &  e.2 & \e.3 then Return func(, a.2)
>   When  e.1 &  e.2 & \e.3 then Return func(a.1, a.2)
>   When \e.1 & \e.2 &  e.3 then Return func(, , a.3)
>   When  e.1 & \e.2 &  e.3 then Return func(a.1, , a.3)
>   When \e.1 &  e.2 &  e.3 then Return func(, a.2, a.3)
>   Otherwise                    Return func(a.1, a.2, a.3)
> End
> 
> Now imagine constructing something like that for 100 arguments.  Your
> routine would run into the millions of hellabytes.
> 
> �R
It only helps in that it's in a subroutine at the end of the code, instead of in 
the mainline of the program. And if all you want is a simple check that the arg 
was passed, and not it's validity, then it could help.

-- 

Les               (Change Arabic to Roman to email me)
0
Reply LesK 7/29/2010 2:43:39 AM

On Wed, 28 Jul 2010 22:43:39 -0400, LesK wrote:
>Glenn Knickerbocker wrote:
>> I'm not sure how the SIGNAL part of this is supposed to help.
>It only helps in that it's in a subroutine at the end of the code, instead of in 
>the mainline of the program.

How is it any more helpful than the much less complicated solution of
using an actual subroutine, though?  It avoids setting RESULT as a side
effect--but at the expense of setting _RETURNLABEL as a side effect
instead.

�R  "MY FLIEGENDE HOLL�NDER WON'T STOP BLEEEEEEING!" --Poot
<http://users.bestweb.net/~notr/magictop.html>     Rootbeer
0
Reply Glenn 7/30/2010 9:37:56 PM

Glenn Knickerbocker wrote:
> On Wed, 28 Jul 2010 22:43:39 -0400, LesK wrote:
>> Glenn Knickerbocker wrote:
>>> I'm not sure how the SIGNAL part of this is supposed to help.
>> It only helps in that it's in a subroutine at the end of the code, instead of in 
>> the mainline of the program.
> 
> How is it any more helpful than the much less complicated solution of
> using an actual subroutine, though?  It avoids setting RESULT as a side
> effect--but at the expense of setting _RETURNLABEL as a side effect
> instead.
> 
> �R  "MY FLIEGENDE HOLL�NDER WON'T STOP BLEEEEEEING!" --Poot
> <http://users.bestweb.net/~notr/magictop.html>     Rootbeer
You can't *directly* access the original variable number of Arg(n) in a subroutine.

-- 

Les               (Change Arabic to Roman to email me)
0
Reply LesK 7/30/2010 10:40:00 PM

On Fri, 30 Jul 2010 18:40:00 -0400, LesK wrote:
>You can't *directly* access the original variable number of Arg(n) in a subroutine.

AHA!  I get it now.  Thanks!

�R                  Blather, Rinse, Repeat.
http://users.bestweb.net/~notr/telecom.html
0
Reply Glenn 8/1/2010 1:08:45 PM

Swifty wrote:
> Can anyone suggest anything more elegant?

You could use the dynamic method part of Object Rexx to on-the-fly code up an appropriate method to handle exactly the number of args being passed in for that instance, then call that on-the-fly method.

The variable pool is funky running in a dynamic method, so one way around that was to have the dynamic method then call / chain onto a private static method which is only to be called by a in-between 
dynamic method... and that gets around the funky variable pool in a dynamic method problem.

At one client, a college of mine coded up a database framework which could interface with any sort of database table structure. There were dynamic methods to directly access each field within the 
record. The above was leveraged to make that work.

Sincerely,

-- 
Michael Lueck
Lueck Data Systems
http://www.lueckdatasystems.com/
0
Reply Michael 8/2/2010 4:14:15 PM

On Mon, 02 Aug 2010 12:14:15 -0400, Michael Lueck
<mlueck@lueckdatasystems.com> wrote:

>At one client, a college of mine coded up a database framework which could interface with any sort of database table structure.

That's more or less what I'm doing. My first parameter is the name of
an SQL cursor. The remaining arguments are the host variables required
to satisfy the "?" substitution positions in the underlying SQL
statement.

So if my SQL had been "Select Name where persnum=?" then my code would
have to do something like:

Call Prepare 'MYNAME','Select name from names_table where persnum=?'
Call open 'MYNAME','085204'

My question was referring to the my open() function, which can take
any number of arguments from 1 upwards. Inside the open() code, I call
the actual SQL function. The SQL function rejects the request if the
number of host variables differs from the number of placeholders ("?")
in the original SQL statement.

-- 
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk
0
Reply Swifty 8/3/2010 7:37:03 AM

Swifty wrote:
> My question was referring to the my open() function, which can take
> any number of arguments from 1 upwards. Inside the open() code, I call
> the actual SQL function. The SQL function rejects the request if the
> number of host variables differs from the number of placeholders ("?")
> in the original SQL statement.

In my associates design, they coded the main class as an abstract class, and I added some logic to the class to guarantee abstractness. (If newClass = me then error / nop)

In the subclass instances, that is where the interface to the actual table structure happens. A simple / compact "AddColumn" method which accepts many args defining that column to the class... which 
that (the parent class) in turn has all of the dynamic method logic.

Since you mention cursor numbers, I assume you are working with the official IBM driver. We were too. One of the args to the AddColumn API was the cursor number... if I remember correctly. Mark 
Hessling's RexxSQL had no exposure as to the cursor number, so that is how the ORexxSQL class library got around hard coding cursor numbers into that class. I will ask to verify if that was where the 
cursor numbers were hidden in the class architecture.

Sincerely,

-- 
Michael Lueck
Lueck Data Systems
http://www.lueckdatasystems.com/
0
Reply Michael 8/3/2010 11:03:47 AM

On 3 Aug, 09:37, Swifty <steve.j.sw...@gmail.com> wrote:
> On Mon, 02 Aug 2010 12:14:15 -0400, Michael Lueck
>
> <mlu...@lueckdatasystems.com> wrote:
> >At one client, a college of mine coded up a database framework which could interface with any sort of database table structure.
>
> That's more or less what I'm doing. My first parameter is the name of
> an SQL cursor. The remaining arguments are the host variables required
> to satisfy the "?" substitution positions in the underlying SQL
> statement.
>
> So if my SQL had been "Select Name where persnum=?" then my code would
> have to do something like:
>
> Call Prepare 'MYNAME','Select name from names_table where persnum=?'
> Call open 'MYNAME','085204'
>
> My question was referring to the my open() function, which can take
> any number of arguments from 1 upwards. Inside the open() code, I call
> the actual SQL function. The SQL function rejects the request if the
> number of host variables differs from the number of placeholders ("?")
> in the original SQL statement.

SQL-hat on:
    '?' is only usefull, if you reuse MYNAME, otherwise direct values
are
    better (and safer - it's often necessary to double-quote in Rexx
to get
    the correct value/type from a Rexx var into the db -
    in your case, it may very well be,
    that the db will receive an INT 85204 - not the (VAR)CHAR '085204'
-
    and not like it)

Rexx-hat on:
    /* a) use a stem */
    cursor1 = "Call open 'MYNAME'"
    do i = 1 to st.0 - 1
        cursor1 = cursor1 st.i || ","
    end
    cursor1 = cursor1 st.i
    interpret cursor1
    (quoting is still not easy)
    (btw., receiving may be similar)

    /* b) use the SQLDA - never done myself */
hth,
Wolfgang
0
Reply wolfgang 8/12/2010 5:15:34 PM

On 12 Aug, 19:15, "wolfgang.riedel" <wolfgang.riede...@web.de> wrote:
> On 3 Aug, 09:37, Swifty <steve.j.sw...@gmail.com> wrote:
>
>
>
>
>
> > On Mon, 02 Aug 2010 12:14:15 -0400, Michael Lueck
>
> > <mlu...@lueckdatasystems.com> wrote:
> > >At one client, a college of mine coded up a database framework which c=
ould interface with any sort of database table structure.
>
> > That's more or less what I'm doing. My first parameter is the name of
> > an SQL cursor. The remaining arguments are the host variables required
> > to satisfy the "?" substitution positions in the underlying SQL
> > statement.
>
> > So if my SQL had been "Select Name where persnum=3D?" then my code woul=
d
> > have to do something like:
>
> > Call Prepare 'MYNAME','Select name from names_table where persnum=3D?'
> > Call open 'MYNAME','085204'
>
> > My question was referring to the my open() function, which can take
> > any number of arguments from 1 upwards. Inside the open() code, I call
> > the actual SQL function. The SQL function rejects the request if the
> > number of host variables differs from the number of placeholders ("?")
> > in the original SQL statement.
>
> SQL-hat on:
> =A0 =A0 '?' is only usefull, if you reuse MYNAME, otherwise direct values
> are
> =A0 =A0 better (and safer - it's often necessary to double-quote in Rexx
> to get
> =A0 =A0 the correct value/type from a Rexx var into the db -
> =A0 =A0 in your case, it may very well be,
> =A0 =A0 that the db will receive an INT 85204 - not the (VAR)CHAR '085204=
'
> -
> =A0 =A0 and not like it)
>
> Rexx-hat on:
> =A0 =A0 /* a) use a stem */
> =A0 =A0 cursor1 =3D "Call open 'MYNAME'"
> =A0 =A0 do i =3D 1 to st.0 - 1
> =A0 =A0 =A0 =A0 cursor1 =3D cursor1 st.i || ","
> =A0 =A0 end
> =A0 =A0 cursor1 =3D cursor1 st.i
> =A0 =A0 interpret cursor1
> =A0 =A0 (quoting is still not easy)
> =A0 =A0 (btw., receiving may be similar)
>
> =A0 =A0 /* b) use the SQLDA - never done myself */
> hth,
> Wolfgang

Sorry,
didn't see the original subject
0
Reply wolfgang 8/12/2010 5:17:31 PM

13 Replies
147 Views

(page loaded in 0.136 seconds)

Similiar Articles:


















7/20/2012 7:30:14 PM


Reply: