[PD] libdir/objectname

katja katjavetter at gmail.com
Thu Oct 16 15:44:14 CEST 2014


Thanks for bringing up this important topic. Over the years I flip-flopped
between [library/objectname] and [declare] a few times, for reasons which
I'll try to explain.

The first occasion where I needed [library/objectname] was when [pow~] in
pd core had it's inlets swapped between pd versions, while [cyclone/pow~]
retained the old inlet order and could be used for backward compatibility.

When Pd-extended stopped loading libraries by default I started using
[library/objectname] for externals from all Pd-extended libraries, which
was recommended practice.

Later, I came across a few cases where externals moved from one lib to
another. For example, [flatspace/knob] became [flatgui/knob]. I feared
further library reorganizations and abandoned the rigid
[library/objectname] format. Now I started to appreciate the flexibility
provided by [declare]. I used declarations like [declare -stdlib
flatspace/knob] and [declare -stdlib flatgui/knob] in top level patches to
make projects compatible across Pd-extended versions. Also, I use [declare]
for binaries which are included in project directories: for my homebrew
binaries, or selected Pd-extended binaries in projects which should run
with vanilla Pd. It is much easier to change or add a few declarations in
the top level patch than changing library names in all object instances in
a large project.

But [declare] only adds search paths and it doesn't protect against name
clash. I came across [bsaylor/svf~] which has different number of inlets
and outlets than [cyclone/svf~]. Without library name, [svf~] instantiates
the cyclone version. But when [bsaylor/svf~] was instantiated earlier in
the Pd session, or with [import bsaylor] in the patch, the bsaylor version
may be instantiated. Without namespace specification Pd seems to use the
version that was loaded first within a Pd session.

I realized that instantiating without library namespaces is a gambling. And
this does not only apply to binary executables, but to abstractions as
well. Imagine you share a Pd project including abstractions and binaries,
and you publish a new version of the project, where bugs in externals were
fixed or new features were added to abstractions. Users may want to compare
versions, and load the old version first in a Pd session. Even when they
close the old version of the project before loading the new version, the
old executables and abstraction definitions are still in Pd's memory, and
Pd will not load the new ones unless they were prefixed by a different
namespace, or until Pd is restarted. So, the new project version may seem
to still contain the old bugs!

The current solution for such issues is systematic use of lib names and
relative paths in object or abstraction instances. For example, include
abstractions in a subdirectory named 'abstractions', and instantiate as
[abstractions/objectname]. Pd will then load the abstraction from the
subdirectory in the project, even when many projects have an 'abstractions'
subdirectory containing an abstraction with the same name. This tedious and
inflexible approach will only work when directory structures don't change.
A project or library structure must be well organized right from the start.
If something changes in the structure, you may need to find all instances
of a class in your patch(es) and redefine them. Rigid directory structures,
and the prospect of minor changes causing heaps of maintenance work, can be
an obstacle for future innovations in a project, or in Pd-extended as a
whole.

In any case, I'm reluctant to use namespaces for each and every instance.
It can make your patch today, and break it tomorrow. It would be super if
[declare] would not only add a search path, but also locally enforce
priority for it. Say I have my own implementation of [svf~] stored in the
'bin' subdirectory of a Pd project directory. The main patch contains
[declare -path bin] and several instances of [svf~]. Pd should search the
bin subdirectory and other locally declared paths for an [svf~] executable.
If Pd finds the one in the bin subdirectory, it should interpret all
instances of [svf~] as [bin/svf~] and instantiate them accordingly. If an
object name appears in two locally declared paths, you would still have a
name clash. But designing a single project directory without name clashes
is not so difficult.

How hard would it be to realize such path priority, I wonder? Currently, Pd
can distinguish between different abstractions with the same name and
relative path prefix, if they appear in different project directories. See
attached test, where different versions
[abstractions/namespace-testabstraction] are instantiated from patches in
two different 'project folders'. Apparently Pd identifies these files with
their absolute path, otherwise it could not load two different versions of
[abstractions/namespace-testabstraction], right?

Katja

On Thu, Oct 16, 2014 at 6:21 AM, Jonathan Wilkes via Pd-list <
pd-list at lists.iem.at> wrote:

> Hi list,
>      Let's say I make a patch that uses the zexy and hcs libraries.  I
> want my patch to be portable to Pd-extended, Pd-l2ork, and whatever
> hand-rolled Pd-vanilla+zexy+hcs installations are sitting out there on
> users machines.
>
> If that is my goal, then I am going to use libdir/objectname syntax for
> all my zexy and hcs objects in my patch.  I am going to do this because if
> a user ever reports that there is a nameclash, it is very likely to be due
> to a bug somewhere, and that bug is very likely to be fixable.
>
> In fact, I will go so far as to say there is no other way to make a
> portable patch that uses externals on the versions of Pd I described
> above...
> * both [import] and [declare] will happen _after_ the the default libs of
> Pd-extended/L2ork are loaded, so I can't use unprefixed object names with
> impunity (same with .pdrc).  And even if it does work, it's not
> future-proof, as someone may add an object that aliases one I'm using in my
> patch.
> * command lines flags don't ship with my patch, and they get parsed
> _after_ the user or default prefs so again, I'm just hoping to get lucky.
> * even with Pd-extended's current "load-nothing" dogma, all possible
> object names are stored globally (in what looks like both prefixed and
> unprefixed forms, like "foo/bar" and "bar").  So if my patch is an
> abstraction and I don't use libdir/objectname syntax for the object names
> within it, all I can do is hope the user hasn't already loaded something
> that aliases one of my objects.  (And again, not future-proof)
>
> I see only two possibilities, then: either the community changes the core
> functionality so that there is a local object-name table for each
> canvas-environment*, or libdir/objectname should be the canonical way to
> make portable patches.  Since libdir/objectname exists and
> "canvas-environment-local namespaces" don't, I suggest libdir/objectname as
> the only workable approach.
>
> However, I'm only about 3/4 of the way through reading and comprehending
> the library-loading code in Pd.  So if anyone has thoughts or suggestions
> I'm all ears.
>
> -Jonathan
>
> * canvas-environment = all canvases which share the same $0-- basically, a
> canvas and its [pd] subpatches (and graphs).
>
> _______________________________________________
> Pd-list at lists.iem.at mailing list
> UNSUBSCRIBE and account-management ->
> http://lists.puredata.info/listinfo/pd-list
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puredata.info/pipermail/pd-list/attachments/20141016/3e768eb5/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: namespacetest.zip
Type: application/zip
Size: 2214 bytes
Desc: not available
URL: <http://lists.puredata.info/pipermail/pd-list/attachments/20141016/3e768eb5/attachment-0001.zip>


More information about the Pd-list mailing list