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!

Calling a subroutine and passing a parameter

Status
Not open for further replies.

dmusicant

Programmer
Mar 29, 2005
252
US
I had a line in a PRG:

Replace recordings with recordings()

Recordings is a field in the open table.

recordings() returns a value determined by PROCEDURE recordings.

When I wrote this, the procedure didn't require a parameter, but I decided to pass a parameter to the procedure, so the first two lines of the procedure then read:

PROCEDURE recordings
PARAMETER tcPasskey

At the end of the procedure was the line
RETURN cresult


So, how do I call PROCEDURE recordings and ask to replace recordings with recordings() if I have to pass a parameter in the call?

IOW, my call to PROCEDURE recordings has to look like REPLACE recordings WITH recordings(passvalue) instead of REPLACE recordings WITH recordings()

I worked around this seeming obstacle by creating a variable cpasskey before my call to PROCEDURE recordings and then referred to cpasskey within PROCEDURE recordings. Am I missing something or did I really have to do it that way?
 
I don't ALWAYS test QUITE as thoroughly as I probably should.

And I once had a situation where we tested TOO thoroughly.

The app was distributed to every federal court, bankruptcy court, and probation office in the US to collect budget requests. We thoroughly tested reporting after data entry but EVERY DOGGONE OFFICE wanted to print the reports before data entry so they could see what it looked like. It crashed badly.

Data entry worked flawlessly, though. [neutral]
 
Production data? What exactly is that? Of course, I didn't test on live data, perhaps I tested on copies of live data. It's been a long time since I had that job, I was officially the "database administrator" but I was the only person on board who had a lot in the way of Visual Foxpro chops, and I used those chops a lot because it made my job a lot more interesting. I had a really good idea what my users were up to, what their experience was day-in, day-out and as time allowed I would dream up enhancements/improvements that would make life easier for my users. It was a mission critical application. My users were all employees of my company, around 200-250, ~80% of whom were at my location, the others scattered around the USA and a few overseas. The ones off site were working in offices at a lot of large, usually high tech firms. Our clients/customers there were employees of those companies, our services were a perk for them supplied by their employer. Our largest corporate client was American Express and our services were extended to their customers. Only employees of my company (local and otherwise) dealt with our application, they interacted with the customers by telephone, email and probably in many cases face to face.

If something went wrong and those services went awry, the onus would have fallen squarely on me and I dreaded that eventuality so I did whatever was necessary to give me confidence that my changes, updates, data maintenance, etc. were OK. I used my imagination! Like I say, it's been over 14 years, so I don't remember the details. That job ended 2 days after 911!
 
Spunds like 911 had an impact on this job, too. My compassion on that.

Let me just refer back to what you said:

dmusicant said:
I'd had to do some debugging that first required my undoing possible damage to data, which required me to reenter data, then run altered code with fingers crossed.

I don't see were you would need to "cross fingers", just because of changing a call without paramters to a call with parameters, when that little change can be tested on data copies instead of live (or as I call it: production) data. It seemed you had no chance to test or you even messed some live data, while it's much easier to test something in VFP and with DBFs than in other languages and databases. For example it has become quite impossible for me to get databases of a customer. Fortunately I have a VPN connection to the customer and the customer has implemented the idea of test databases and staging changes on the customer site.

It seems there is much more involved what you didn't mention and show here, but it seemed your thoroughly tests were rather theoretical and not simply practical test runs against data copies. Even though you never can be 200% sure what happens whwn something goes live and there are those hopefully fewest bugs hitting the end user, I would be more confident about such a change. If something like that made you cross fingers, then I thought it would perhaps be good to talk about possibilities of testing. You're still far from praying or hiring body guards, but I didn't and still don't understand why you are so unsure about that code change, as the detail we talked about here was a very small change.

Bye, Olaf.
 
Recordings is not a good method/function/procedure name. A good name will tell you What it does, for example, GetRecordingByKey or some such thing. That should help you to not confuse all the recording references.

BTW, it doesn't matter if you declare it a function or procedure. It's how you call it that makes a difference.

DO GetRecordingByKey is a procedure
GetRecordingByKey() is a function

The code in GetRecordingByKey can be identical.

Craig Berntson
.Net MVP, Author, Tech Presenter
 
In this case (this last week) my user was myself, the only person to fear if I goofed was me! :)

Olaf said:
I don't see were you would need to "cross fingers", just because of changing a call without parameters to a call with parameters,

I was confident when I first ran it, but it bombed, so I had to scour the code and determine what went wrong. One of the elements of the SQL SELECT command in the 2nd incarnation of the function didn't exist in that scenario... Whoops!

The result was that I had to:

1. Find out why the code had failed. The failure was opaque, I couldn't see anything. The application went into SUSPEND. That puzzled me. I am thinking that I may have set up an ON ERROR that put the app into SUSPEND. That's all I can think of. I can investigate that, however things are working now and I don't feel a need to get to the bottom of that right now.

2. AFTER fixing the problem (which I couldn't be sure of) I had to restore data to where it was before I ran the code that messed up. That code runs after some data entry. Changes were made to permanent and temporary data. There wasn't much data involved, so reentering the data only took around 10 minutes, I wasn't very put out.

My biggest concern was making sure my code was fixed. In fact, it was just yesterday when I had a chance to enter more such data (a lot more this time!) and see if the code worked OK and permanent files properly updated. I should really have backed up data before saying "Y" to the question of whether or not I was prepared at that point to update the permanent tables, however I forgot to do so! Anyway, when I checked the permanent files they looked fine.

I could have worked out a test scenario to make sure things were OK, but figured it wasn't worth the bother. It wouldn't have been a big deal if I had to fix things and reenter data again, a 2nd time. However, as I say, I didn't even bother to back up my temporary tables before executing the transfer to permanent tables (which also zaps the temporary tables). I guess I was fairly confident (actually I was forgetful!). I think so-called Murphy's Law is hogwash.

 
Craigber,

Mike Lewis already pointed out that they might not be identical. DO PROCEDURE WITH defaults to parameters sent by reference, functions by value.

Change the value of a parameter in a procedure changes it.

Change the value of a parameter in a function, may or may not change it. Depending on how the
function was called.

Call a procedure as if it was a function and... I would need to test that!


Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are not good for you.
 
While you would be advised to not mess with what works, FYI Help lists the default behavior of how () parameters are passed can be changed with SET UDFPARMS TO VALUE|REFERENCE. I believe the default is VALUE. Note that DO|WITH always defaults to REFERENCE.
 
Correct, dbMark, but DO is out of consideration, as you can't make a DO inside a query, you need the call syntax with just procedure name and optional brackets. The brackets should be put after the procedure or function name anyway to denote this is a call and not a key word or field or variable name or expression. And it was that way already, wasn't it? So the only thing that changed is adding parameters inside the brackets and the procedure receiving parameters with LPARAMETERS. It's no big fuss. Passing by reference or as value also is of no importance here. From a query you typically pass in fields and even if you SET UDFPARAMS TO REFERENCE and pass in fields "by reference" they come in as value, their modification does not alter the the source tables or cursors the value come from -which you could expect from by reference calls - only the return value is of importance.

If you can't see that, dmusicant, I can only assume you never ever left your comfort zone of well known legacy code. Functions are no magic, they are even not oop, they are a really basic programming concept.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top