[pmwiki-users] Request input on soon-coming FAST Data release

Crisses crisses at kinhost.org
Mon Oct 9 08:45:57 CDT 2006


On Oct 9, 2006, at 8:35 AM, The Editor wrote:

>> I'm not particularly interested in cut & paste code -- I'm VERY  
>> interested in coming up
>> with new recipes, using it to customize data.
>
> Part of my goal is to help those like me who don't know PHP but want
> to be able to do all kinds of interesting things.  This recipe should
> make that possible.  For those who want to hack the code, or use it in
> different ways, I want to make the code easy to modify.  For example,
> if I had been paying attention, I should have suggested you put the
> simile wrapper actually as a simple conditional in the engine itself.
> It would have been easier for you and been more in harmony with my
> original design goal of extensibility.  I guess I should have
> explained how to do this.

I don't want to do that.  I want modules I can upgrade without  
breaking a site. I do understand that things would probably break  
from FastData2 to whateveryoucallit3 -- that's a major revision --  
but I don't want them to break from upgrading due to a security fix.   
I only hacked the code as you recommended so that it would create  
data pages that PageLists et al would work with.

Otherwise I prefer to work in a separate cookbook recipe or in  
config.php.  That's where hacks & customizations ought to be.

>> One nice thing about the way similepedia.com is using FASTData is  
>> that it's NOT being
>> used to retrieve data from pages.  Only to create the data pages.   
>> I have one form that
>> uses it.  I can easily restrict editing on the form page, and have  
>> PmWiki ONLY load
>> FASTData when loading the one page... then my security is done...
>
> Yes, I wonder if I still even need data retrieval capabilities with
> the new text variables.  Very powerful. Same thing, soon, with the
> logging features (commenting).  As more and more stuff gets added to
> core, less and less may be required of FAST Data.  Which may solve the
> length problem a different way.

I am using the new text variables.

>> Another thing that's important to keep in mind:  Namespace.  I've  
>> been trying to keep the > vast bulk of my (newer) cookbook recipes  
>> within a function or class.  The problem is that > every time you  
>> create a variable you risk bumping into conflicts between your  
>> variable
>> name(s) and those of other recipes.  This also goes for function  
>> names.
>
> Can you explain what you mean by classes?  I don't think you can
> define functions within functions can you?  And to have values passed
> between functions you pretty much need globals, unless you pass them
> as function paramaters.  Is there much advantage to one or the other?

Classes are a code structure from the object-oriented-programming  
side of PHP.  It usually takes a while to wrap one's head around it.   
And I've never EVER found a terrific explanation of what classes are.

A class is beyond a function.  The class definition creates an ideal  
"object" (rather than an actual object, that comes later), and  
assigns it properties (variables) and methods (functions).

Here's the basic class syntax for how I would deal with shoelaces  
(I'm using comments for a real life action that I don't feel like  
emulating in real code) -- but note that an "object" does not need to  
be a physical object -- it could be an email, data, graphics, form  
buttons, or something even more abstract.

class Shoelaces {
	$tied = false;
	$double = false;
	
	function tie_shoelaces () {
		if ($this->tied) { return; }
		// instruction to grab shoelaces here
		$this->pull_tight();
		$this->overhand_knot();
		$this->pull_tight();
		$this->make_loop("right");
		$this->make_loop("left");
		$this->overhand_knot();
		$this->pull_tight();
		if($this->double) {
			$this->overhand_knot();
			$this->pull_tight();
		}
	}

	function pull_tight() {
		// yank whatever is in your hands in opposite directions
	}
	function overhand_knot() {
		// loop item in right hand around item in left hand one complete  
rotation
		// hold item in right hand again
	}
	function make_loop($side) {
		// creates a loop from the left or right side of the lace
	}
}

Here's how you use the class:

// create an object instance -- this is a specific local copy of the  
class for this specific instance/call.  This code would be in the  
master body of your program -- or in another function
$bootlaces = new Shoelaces;
// set the properties
$bootlaces->tied = false;
$bootlaces->double = true;
// tie the shoelaces (call the method i.e. execute the function)
$bootlaces->tie_shoelaces();

Now you should have a doubleknotted shoelace on your boots.  This  
could be used for sneakers also.  Or even hacked for tying laces on  
other objects.

Now, the parts people have the hardest time wrapping their brain around:

	Calling it "object" "method" "instance" etc.  -- It's a prepackaged  
set of code, values and actions/functions.

	the term "this" inside the class definitien -- $this is "$this  
object"  or a place holder for the namespace INSIDE the object.

There is no place to run code in the object without defining a  
function/method.  It's confusing to call it an object method when  
obviously you're even using the syntax "function" :P

I didn't use it above, but there's also something called a  
"constructor method" and in PHP5 there's a destructor method.  All  
this means is "automatically run this function when I create the  
class instance" or a destructor is something auto-run when you  
destroy the object instance (not sure how, I don't do PHP5 yet --  
maybe unset()?)

Syntax for a constructor in PHP4 is to name the constructor function  
the same name as the class name -- inside the class definition.

	function Shoelaces() {}


I know this is probably confusing, so feel free to ask questions.   
Note however that this completely protects the code and variables of  
the class from colliding with the names of other items in the  
program.  The only name of concern is the class itself.  Other people  
can use your class pretty easily -- it makes a very portable chunk of  
code.  There's more to it, but this is enough to actually get you  
using this idea if you decide it would make code more efficient.

>> Once your function is defined, your namespace is local instead of  
>> global.  The same
>> goes for objects/classes.  Much safer in a shared programming  
>> environment.
>
> Again, I don't really know what you mean by namespace, though I've
> heard the expression before.  Help?

hrm.  Ok -- namespace is a term used in regard to labels (names) used  
for memory/variables in the execution of the code ($a, $fancy,  
MyFunction()).  The "space" portion refers to the scope of the name  
(local scope, global scope, etc.).  Variables in the global namespace  
would be a list of the variables used in the normal program execution  
(not within function), or defined as global in a function (if a  
function is passing information to the global execution by defining a  
new global variable).  In PmWiki's global namespace, Patrick uses $n  
$pagename and functions like UpdatePage.  If you want to iterate  
through a list and use
	for($n=0; $n<5;$n++) {}
there is going to be a problem in the normal code execution if any  
other code later is expecting $n to be the old value.  This would be  
a namespace collision.  PHP has no good protection against namespace  
collisions for variables.

It does for function names though:  You can't name a function  
UpdatePage or you will get an error (if UpdatePage is already  
defined) or cause PmWiki.php's definition of UpdatePage to generate  
an error.  You can overwrite $pagename and get in trouble during  
PmWiki execution (or take advantage of it on purpose).

Variables defined within functions have their own separate  
namespace.  You need to specifically pull in normal global variables  
or pass information by argument, or use superglobals.

classes also create new scope for naming variables and functions.

You may not collide with Patrick's code, but you probably haven't  
tested your code with every plug-in.  If most of your code is inside  
a function, just make sure the function itself doesn't clash with  
other potential or existing functions.  If you name it "Data" it's  
more likely to collide than if you name it "FD_Data" -- it's one of  
the unofficial conventions when creating cookbook recipes -- it  
should be stressed a bit more for clarity, portability, and allowing  
the most flexibility in cookbooks:

1) keep as much code as possible in a protected namespace (class or  
function)
2) name said class or function with something to separate it from  
other recipes or pmwiki code (FD_Data)
3) the same should go for newly-introduced values that need to be  
addressed in config.php

Is that helpful?

>> A good example of code that should be in an included file for your  
>> recipe is the
>> FastData->Database functions.  I also highly recommend that you  
>> follow the discussion
>> of encouraging cookbook cooks to use adodb instead of writing code  
>> for a single type of
>> database.  In any case, not everyone is using a database, and the  
>> code may be pretty
>> long.  If they don't have adodb called before your recipe, your  
>> recipe might even break
>> because your database functions are calling on functions / classes  
>> that are not defined.
>> If it's in an include, you can check that adodb was loaded AND  
>> that the code is needed
>> before loading the database functionality.  That could save  
>> another 500 lines of code from
>> being called.  ;)
>
> I'm still chewing on whether I want to split up the recipe into
> modules or keep it all together.  Haven't come to a conclusion yet.  I
> tend to think the easiest is having those concerned about performance
> simply delete any functions they don't need.  Perhaps a bit of help
> explaining how to do this could be helpful.  ie, which functions are
> required for which features.

I really do not want to edit your recipe when I download it.  It  
loses all its plug-and-playness and would need to be re-hacked every  
time you update for something routine or important without changing  
the basic functionality of the application.  Also, I could be using  
ALL your functions, but not every time a single form is used -- this  
one there, that one somewhere else.  If I want to keep the recipe in  
tact, compartmentalizing it and only calling the needed functions is  
really the best way I can think to go about it.  Yes, it's more files  
to keep track of, but it also helps you think about how you've  
organized your code.

Now, if you need help looking at your code from a new perspective, I  
suggest you ignore the 500 line barrier and document the code -- a  
lot.  Then people can look at it, make suggestions to improve it,  
make suggestions as to how you could have it execute more smoothly, etc.

Crisses
-------------- next part --------------
An HTML attachment was scrubbed...
URL: /pipermail/pmwiki-users/attachments/20061009/b0eca49d/attachment.html 


More information about the pmwiki-users mailing list