[octvae forge] shadowing between packages

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

[octvae forge] shadowing between packages

JuanPi
Hi all,

I need to ask suggestion on how to solve the following situation:

1. Package A implementes funcA
2. Package B also implementa funcA, but is much better than A's funcA
3. Package B depends on Package A

Clearly Package A needs to run on itself, and if Package B is loaded
funcA is now pointing to B's funcA... this means functions from A
using funcA might fail (e.g. signature incompatibility)

What solutions do you have?

We have considered:
1. Renaming B's funcA to funcA_B ... not ideal, but well if that's it...
2. Creating a new package mirroring A, that renames funcA into funcA_A
... breaks all A's functions as does the shadowing, unless done
everywhere
3. Renaming functions of package A when package B is loaded, and
putting them back when package B is unloaded

2. is done via CVS, but as said is not actually a solution, unless one
renames everythig
3. We do not know actually how to do it! :D

Is 1. the only solution?

Thanks
--
JuanPi Carbajal
https://goo.gl/ayiJzi

-----
“An article about computational result is advertising, not
scholarship. The actual scholarship is the full software environment,
code and data, that produced  the  result.”
- Buckheit and Donoho

Reply | Threaded
Open this post in threaded view
|

Re: [octvae forge] shadowing between packages

apjanke-floss


On 3/16/19 8:28 PM, JuanPi wrote:

> Hi all,
>
> I need to ask suggestion on how to solve the following situation:
>
> 1. Package A implementes funcA
> 2. Package B also implementa funcA, but is much better than A's funcA
> 3. Package B depends on Package A
>
> Clearly Package A needs to run on itself, and if Package B is loaded
> funcA is now pointing to B's funcA... this means functions from A
> using funcA might fail (e.g. signature incompatibility)
>
> What solutions do you have?
>
> We have considered:
> 1. Renaming B's funcA to funcA_B ... not ideal, but well if that's it...
> 2. Creating a new package mirroring A, that renames funcA into funcA_A
> ... breaks all A's functions as does the shadowing, unless done
> everywhere
> 3. Renaming functions of package A when package B is loaded, and
> putting them back when package B is unloaded
>
> 2. is done via CVS, but as said is not actually a solution, unless one
> renames everythig
> 3. We do not know actually how to do it! :D
>
> Is 1. the only solution?
>
> Thanks
>

Namespaces. Or classes.

If Package A's funcA is for A's internal use, or has distinct semantics
from Package B's funcA, it could go in a +pkgA namespace. And Package
B's funcA could go in +pkgB. That way they can coexist, and each package
calls its own funcA(). Instead of a namespace, you could also make them
methods on distinctly-named classes in Package A and Package B.

If you want to replace them globally and dynamically, such that both
packages will be calling the same funcA() implementation, but you can
select which one at runtime, then you could use a "factory" pattern:
Have a global func_a_provider class or function that returns a function
handle to a funcA implementation. It uses one of them as a default. And
it provides a "register" behavior that allows code to replace the
default funcA implementation with another function (or class) at run
time. Java and similar languages use "factory" and "service provider
interface" patterns to do this.

Cheers,
Andrew

Reply | Threaded
Open this post in threaded view
|

Re: [octvae forge] shadowing between packages

JuanPi

Hi Andrew
Thanks. I sounds to me that the namespace solution is the best, since we do not have control over package A development.
I would then add a load script to package B to create the namesspace. Honestly i have not yet work with packages namespaces so i am not sure if this can be achieved at runtime.
Another solution is to add the namespace in the mirror of package A. Maybe that's better

Reply | Threaded
Open this post in threaded view
|

Re: [octvae forge] shadowing between packages

apjanke-floss


On 3/17/19 7:02 AM, JuanPi wrote:
> Hi Andrew
> Thanks. I sounds to me that the namespace solution is the best, since we
> do not have control over package A development.
> I would then add a load script to package B to create the namesspace.
> Honestly i have not yet work with packages namespaces so i am not sure
> if this can be achieved at runtime.
> Another solution is to add the namespace in the mirror of package A.
> Maybe that's better
>

Doing namespaces dynamically is hard, because it means that you have to:
a) rearrange the source files on disk to put them in a namespace before
you add them to the path, and
b) transform the code itself so function references now refer to the
namespaced function, instead of the global non-namespaced one.

Usually, namespaces are just done statically.

Can you point me at a concrete example of Package A and Package B here,
so I can better understand your requirements, and maybe make better
suggestions?

Cheers,
Andrew

Reply | Threaded
Open this post in threaded view
|

Re: [octvae forge] shadowing between packages

JuanPi
Hi Andrew,

The case is for geometry and matgeom, in particular function clipPolygon
(mercurial) https://sourceforge.net/p/octave/geometry/ci/default/tree/
(git) https://sourceforge.net/p/octave/matgeom/ci/master/tree/

> Doing namespaces dynamically is hard, because it means that you have to:
> a) rearrange the source files on disk to put them in a namespace before
> you add them to the path, and

I am already doing this anyway. For example I am erasing functions
that shadow core functions (e.g. deg2rad), so I could slightly change
this to put all these functions into a namespace.

> b) transform the code itself so function references now refer to the
> namespaced function, instead of the global non-namespaced one.

ok, based on my ignorance, I thought namespace would work as the
folder private. If global is the first scope where functions are
looked for, then namespaces offer no advantages (for this case) over
the order of loading the packages, i.e. load pkg A first then pkg B to
shadow functions in pkg A, and live with the consequences...
--
JuanPi Carbajal
https://goo.gl/ayiJzi

-----
“An article about computational result is advertising, not
scholarship. The actual scholarship is the full software environment,
code and data, that produced  the  result.”
- Buckheit and Donoho

Reply | Threaded
Open this post in threaded view
|

Re: [octvae forge] shadowing between packages

apjanke-floss


On 3/18/19 3:52 AM, JuanPi wrote:

> Hi Andrew,
>
> The case is for geometry and matgeom, in particular function clipPolygon
> (mercurial) https://sourceforge.net/p/octave/geometry/ci/default/tree/
> (git) https://sourceforge.net/p/octave/matgeom/ci/master/tree/
>
>> Doing namespaces dynamically is hard, because it means that you have to:
>> a) rearrange the source files on disk to put them in a namespace before
>> you add them to the path, and
>
> I am already doing this anyway. For example I am erasing functions
> that shadow core functions (e.g. deg2rad), so I could slightly change
> this to put all these functions into a namespace.
>
>> b) transform the code itself so function references now refer to the
>> namespaced function, instead of the global non-namespaced one.
>
> ok, based on my ignorance, I thought namespace would work as the
> folder private. If global is the first scope where functions are
> looked for, then namespaces offer no advantages (for this case) over
> the order of loading the packages, i.e. load pkg A first then pkg B to
> shadow functions in pkg A, and live with the consequences...

Nope. Namespaced functions don't work like private/. Like static class
methods, they are only looked for if explicitly referenced using their
namespace-qualified name. (It's a bummer. There's an "import" command to
deal with this, but it is scoped to functions, not files or classes, so
it's not a whole lot of help.)

I don't envy you this work.

If this were me, I would beg the authors of these packages to move their
functions into namespaces (providing optional global-function shims for
back-compatibility).

Cheers,
Andrew

Reply | Threaded
Open this post in threaded view
|

Re: [octvae forge] shadowing between packages

Richard Crozier


On 18/03/2019 13:38, Andrew Janke wrote:

>
>
> On 3/18/19 3:52 AM, JuanPi wrote:
>> Hi Andrew,
>>
>> The case is for geometry and matgeom, in particular function clipPolygon
>> (mercurial) https://sourceforge.net/p/octave/geometry/ci/default/tree/
>> (git) https://sourceforge.net/p/octave/matgeom/ci/master/tree/
>>
>>> Doing namespaces dynamically is hard, because it means that you have to:
>>> a) rearrange the source files on disk to put them in a namespace before
>>> you add them to the path, and
>>
>> I am already doing this anyway. For example I am erasing functions
>> that shadow core functions (e.g. deg2rad), so I could slightly change
>> this to put all these functions into a namespace.
>>
>>> b) transform the code itself so function references now refer to the
>>> namespaced function, instead of the global non-namespaced one.
>>
>> ok, based on my ignorance, I thought namespace would work as the
>> folder private. If global is the first scope where functions are
>> looked for, then namespaces offer no advantages (for this case) over
>> the order of loading the packages, i.e. load pkg A first then pkg B to
>> shadow functions in pkg A, and live with the consequences...
>
> Nope. Namespaced functions don't work like private/. Like static class
> methods, they are only looked for if explicitly referenced using their
> namespace-qualified name. (It's a bummer. There's an "import" command to
> deal with this, but it is scoped to functions, not files or classes, so
> it's not a whole lot of help.)
>
> I don't envy you this work.
>
> If this were me, I would beg the authors of these packages to move their
> functions into namespaces (providing optional global-function shims for
> back-compatibility).
>
> Cheers,
> Andrew
>


I wrote some code to automatically refactor a bunch of functions in a
directory to convert them into a +package and use the full namespaced
calling syntax inside all the function files where they call each other.

If this sounds useful to you I can share it with you. You could probably
set up a script to convert matgeom every time a new version is produced.

Regards,

Richard

The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336.