Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Something for the week (end) 3

Status
Not open for further replies.

vgulielmus

Programmer
Jan 27, 2014
522
RO
The weekend is almost gone, but I miss the activity in this forum.

aa is a procedure with 3 parameters.
First call of the aa procedure is without the second parameter.
The second call pass .F. to the second parameter.
The first and the third parameter are integers, and the second is logical.

The question is how can distinguish the two calls ?
There is at least one solution, involving three (supplementary) lines / function calls in the aa procedure.

Code:
aa(1,,2)
aa(1,.F.,2)

PROCEDURE aa
	LPARAMETERS p1,p2,p3
* How can distinguished the two calls
* in the first call p2 is missing
* in the second call p2 = .F.
ENDPROC


Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
I'm looking for solutions for this particular case only (exactly this code, where "aa" is called from the main prg)

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
I don't know, if you had this in mind:

? laStack(AStackInfo(laStack)-1,6)

Bye, Olaf.
 
This is the basic idea. [smile]

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
I had in mind something like this:

[tt]FUNCTION aa
LPARAMETERS p1, p2, p3
AStackInfo(laInfo)
lcLine = laInfo(6)
lcParams = STRTRAN(STREXTRACT(lcLine, "(", ")"), " " , "")
IF AT(",.F.,", lcParams) > 0
* .F. passed as second param
ENDIF

ENDFUNC[/tt]

I see Olaf beat me to the general idea.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
OK, well then how about that:

? Empty(laPara[ALines(laPara,StrExtract(laStack(AStackInfo(laStack)-1,6),"(",")"),11,",")-1])
* -1 explained: Alines will give number of Parameters, if you're interested in Parameter 2 instead of 3 you have substract 1.
* That's a bit tricky and stops working, if only 2 or less Parameters are passed in,
* in general you'd writ a bit more verbose code and see whether the second array element a) exists and b) is empty
* it's not the end, as the call may use a function for the first parameter, which may have additional Parameters making ALINES too simple.
* In the end you need to parse code.

Bye, Olaf.
 
Indeed, this is the solution that I had in mind, or, better say, one of the many variations.

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Olaf Doschke said:
stops working, if only 2 or less Parameters are passed in

I agree, but one (more) general solution can be imagined, combining astackinfo(), pcount() and type()
Also a more complicated situation is when at least one parameter is of character data type.

Thank you for the answers and I hope it was an enjoyable exercise :).

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Yes, it was indeed an enjoyable exercise.

I would have gone to a bit more trouble to make the solution more generic, but I took on board your point about the function always being called from the main program, and always with the same pattern of parameters. Also, my solution might have failed if the calling line included a comment, and the comment contained something that might have been mistaken for the parameter sequence.

And of course the solution would always fail if the source code was not available.

But still an interesting little diversion.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I forgot, according to tradition, I believe, I must present my solution.
Code:
aa(1,,2)
aa(1,.F.,2)

PROCEDURE aa
	LPARAMETERS p1,p2,p3
* How can distinguished the two calls
* in the first call p2 is missing
* in the second call p2 = .F.
	ASTACKINFO(la)
	ALINES(la2,la[1,6],",")
	?LEN(la2[2]) && p2 is missing when = 0
ENDPROC

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Thanks, that was a nice task, though it was inevitable you had to look into astackinfo.

I should also add, you have to build with debug info checked, or astackinfo is not returning code at runtime.

Pcount of course cannot be used, as it's 3 in both cases. At first I thought about List Memory and even Isblank(), but there is no difference there.

In .NET (and other languages) you'd have overloading of the same method with several signatures (result and parameter types) for that matter, besides parameter default values, which you can halfwhat emulate via code lines Pn = EVL(Pn,defaultvalue) at the start of functions/methods, though not explicitly for boolean Parameters, because you'd always override .f. this way.

Astackinfo may help a bit, but I'd rather define such problematic boolean parameters as 0 or 1 instead - or a bit more tricky .NULL. and .T., where .NULL. and .F. swap their meaning. Not using the .F. as a possibly passed in value, a .f. in the parameter variable can only mean, the parameter was skipped.

Bye, Olaf.



 
Talking of PCOUNT(), it's interesting that in early versions of VFP, it was flagged as "for backward compatibility only", with the recommendation to use PARAMETERS() instead. That seems no longer to be the case. In fact, the Help now says that "PCOUNT() may be preferable in most programming situations", because of the way that PARAMETERS() gets reset when a new function is called.

Of course, this doesn't affect the solution to this exercise; it's just an interesting side note.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Any proposal for the next weekend ?
I have something in mind, also easy, and I hope, cute.


Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
I'm inclined to take some responsibility for PCOUNT() no longer being labelled as being for "backward compatibility." Here's some of what we wrote in HackFox:

PARAMETERS(), the FoxPro version, tells you how many parameters were passed in the last function or procedure call. PCOUNT(), supposedly added only for dBASE compatibility and not even listed in the Help index before VFP 5, tells you how many parameters were passed to the routine you're now in. This time, we think dBASE got it right.

Tamar
 
The difference between PCOUNT() and PARAMETERS() is well known, too. Like many things I got this from wOOdy.
Anyway it somewhat resembles the differences of @@IDENTITY (compares to PARAMETERS) vs SCOPE_IDENTITY() (compares to PCOUNT) vs IDENT_CURRENT(‘tablename’).

Bye, Olaf.
 
One more Story this reminds me about:

Some years ago I experimented with the concept of parameter objects to introduce the features of default values and named parameters and also knowing what really is passed in. I already said parsing of parameters is not always as easy, eg if you call aa(bb(f,g(x)),,h(r[5])). Alines fails with this, as separating by comma isn't good enough.

Anyway, that is just the motivation. Now of course a solution is to always just have LPARAMETERS loParams, PCOUNT can then only be 0 or 1. You can predefine such parameter objects, the properties can be seen as parameter names and you can preset default values. You can optionally skip parameters, not only by setting them .NULL., but by removing them from the object. Besides you may always pass back results in that object, as it's known to the caller, of course, and always passed by reference.

I put these thoughts into thread184-949564
I proposed a function creating such objects in thread184-1284242
I don't find where I posted this function first, though, but that's just a side note there is at least one more thread about this.

I had a slight discussion with Christof Wollenhaupt, I think when he still was Christof Lange. The parameter signature gives a function a "face". If you put all parameters into an object you won't get into trouble with too many parameters that easily, eg because of a comma for optional parameters too much. You will have a harder timer debugging things, though, needing to inspect the object and of course the call isn't straight forward anymore. Well, in regard of "straight forward" the same applies to classes vs functions, you first need to create a class instance before calling its method. And still classes have many advantages. Now you need to create a parameter object instance before making a call. I still like this, but it also has some downsides, eg the responsibility to release the objects at the caller, though the class or function encapsulates the knowledge to create them.

Bye, Olaf.
 
PS, I forgot one obvious big disadvantage: Not having IntelliSense about the parameters, if there only is LPARAMETERS loParams. You would need IntelliSense about the object itself, its propertiy names, but also in regard of type and which are optional and what they mean.

Bye, Olaf.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top