On Nov 16, 2011, at 20:02, Bradley Giesbrecht wrote:

> On Nov 16, 2011, at 5:49 PM, Ryan Schmidt wrote:
> 
>> [1] Granted, this is also confusing: the second argument of 
>> php5extension.setup is assigned to the local variable "version", which is 
>> different from the MacPorts global option of the same name. That's why later 
>> you see the otherwise odd-looking:
>> 
>>   version                     ${version}
>> 
>> It would be clearer if I used a different local variable name in the proc 
>> declaration, one which does not conflict with existing options / globals.
> 
> Thanks for the explantations. I did use your php5extensions PortGroup as a 
> starting point, so I guess you are the root of some of my confusion. I'm so 
> kidding :)

True though. The job of a portgroup is to simplify things for portfile authors, 
but in the process of doing that, the portgroup itself can get a bit 
complicated.


> So is declaring an "option" something like a shorthand so you don't have to 
> use "set" to set or change a var value?

options are like global variables you don't have to use "set" to set, but 
they're more than that. For example, they get -append and -delete procs added 
to them. configure.args, depends_lib, etc. are all options. So just like you 
have configure.args-append, by declaring e.g. php5pear.channel as an option, 
you now have the procedures php5pear.channel-append and php5pear.channel-delete 
available. These procs might not make sense for every one of your options, but 
they're there nonetheless if you want them.

The most important difference between variables and options though is that 
options are evaluated lazily. This means an option's default is not evaluated 
when it's declared; it's evaluated when it's first used. You're already 
familiar with this behavior from many of the options in MacPorts base. Consider 
these MacPorts options and their default values:

default distname {${name}-${version}}
default worksrcdir {$distname}

This code executes the moment the parser hits the line "PortSystem 1.0" at the 
top of a portfile. name and version haven't been defined yet, but that's fine; 
MacPorts has just set up distname so that, the first time something tries to 
use its value, it'll figure out what name and version are then. Same with 
worksrcdir: it's set up so that the first time it's read, it'll take the 
current value of distname. In many ports, you'll change distname, and then 
expect worksrcdir to have changed along with it. And this works, because you 
hadn't tried to read worksrcdir until after you set distname.

Example from the php5extension portgroup:

options php5extension.extension_dir
default php5extension.extension_dir {[exec ${prefix}/bin/php-config 
--extension-dir 2>/dev/null]}

If that [exec] were evaluated the instant the parser reached the "PortGroup 
php5extension 1.0" line in the portfile, that would cause an error if the user 
hadn't installed the php5 port yet, which provides the php-config executable. 
Instead, that [exec] is not run until ${php5extension.extension_dir} is first 
read (which, looking further into the portgroup, is in a pre-configure block, 
which won't run until after the php5 port is already installed).

That's what the extra set of curly braces surrounding the default are, by the 
way. If those weren't there, it would be evaluated immediately.


> Now I think I know how to accomplish this, where I want to change a var to 
> non-default if the Portfile passed in an arg:
> option php5pear.channel
> option php5pear.packagexml
> proc php5pear.setup {package.name package.version {package.channel 
> "pear.php.net"} {package.packagexml "package.xml"}}
> php5pear.channel                      ${package.channel}
> php5pear.packagexml           ${package.packagexml}

First, remember it's "options", not "option". Then, I assume you meant those 
assignments to be inside the proc:

options php5pear.channel
options php5pear.packagexml
proc php5pear.setup {package.name package.version {package.channel 
"pear.php.net"} {package.packagexml "package.xml"}} {
    php5pear.channel                    ${package.channel}
    php5pear.packagexml         ${package.packagexml}
    ....
}

Yes, you could do that. The only problem is you've decided that not only does 
the namespace "php5pear" belong to your portgroup, but also "package". Yes 
they're in fact local variables in this proc.... but I don't think we've used 
variables whose names contain a dot in this manner before. They've always been 
top-level global entities, and the part before the dot is there to create a 
pseudo-namespace, to ensure there's no ambiguity. Long story short, I'd just 
use "normal" variable names for proc arguments. Using an underscore instead of 
a dot would be fine for example.

proc php5pear.setup {package_name package_version {package_channel 
"pear.php.net"} {package_packagexml "package.xml"}} {
    ....
}

In the setup proc, I'd only put the most essential parameters. name, version, 
channel is probably necessary. What about package.xml? None of the 500+ pear 
ports you added so far use it, unless I did my grep wrong. If the odd port here 
or there needs to override the package.xml, I'd just let that port set that 
option directly, as in:

PortSystem 1.0
PortGroup php5pear 1.0

php5pear.setup foo 1.2.3 channel.example.com
php5pear.packagexml otherpackage.xml

....

And the portgroup would define the default value, as in:

options php5pear.packagexml
default php5pear.packagexml package.xml


_______________________________________________
macports-dev mailing list
[email protected]
http://lists.macosforge.org/mailman/listinfo.cgi/macports-dev

Reply via email to