Best Way to Resolve Circular Module Loading - raku

I'm trying to have two different objects that refer to each other and also use type checking on the attributes. When I do this I get Circular module loading detected trying to precompile. Googling gets me https://docs.raku.org/language/faq#Can_I_have_circular_dependencies_between_modules? which states:
Note that Raku has no “1 file = 1 class” limitation, and circular dependencies within a single compilation unit (e.g., file) are possible through stubbing. Therefore another possible solution is to move classes into the same compilation unit.
I'd rather not put both classes into the same unit if I can avoid it. I'm not sure how to accomplish this with stubbing since there is no example. The following is a small example of what I'm trying to do:
Yak.rakumod
unit class Yak;
use YakStore;
has YakStore $.yak-store is rw;
YakStore.rakumod
unit class YakStore;
use Yak;
has Yak $.yak is rw;
yak.rakutest
use lib '.';
use Test;
use Yak;
use YakStore;
plan 2;
my $yak-store = YakStore.new;
my $yak = Yak.new(:$yak-store);
$yak-store.yak = $yak;
isa-ok $yak-store.yak, Yak;
isa-ok $yak.yak-store, YakStore;
Yeah, I know, the test is lame, but I just wanted to illustrate the problem. Thanks!

The best way to deal with circular dependencies is to turn your circle into a triangle – that is, to make both classes that would depend on each other instead depend (at least in part) on some third Role.
Here's how that might look with the example you provided and a Shaveable role (Yaks should be Shaveable, right?):
Shaveable.rakumod
unit role Shaveable;
Yak.rakumod
use YakStore;
use Shaveable;
unit class Yak does Shaveable;
has YakStore $.yak-store is rw;
YakStore.rakumod
use Shaveable;
unit class YakStore;
has Shaveable $.yak is rw;
With that change, the tests in your example now pass.

Related

Separating operator definitions for a class to other files and using them

I have 4 files all in the same directory: main.rakumod, infix_ops.rakumod, prefix_ops.rakumod and script.raku:
main module has a class definition (class A)
*_ops modules have some operator routine definitions to write, e.g., $a1 + $a2 in an overloaded way.
script.raku tries to instantaniate A object(s) and use those user-defined operators.
Why 3 files not 1? Since class definition might be long and separating overloaded operator definitions in files seemed like a good idea for writing tidier code (easier to manage).
e.g.,
# main.rakumod
class A {
has $.x is rw;
}
# prefix_ops.rakumod
use lib ".";
use main;
multi prefix:<++>(A:D $obj) {
++$obj.x;
$obj;
}
and similar routines in infix_ops.rakumod. Now, in script.raku, my aim is to import main module only and see the overloaded operators also available:
# script.raku
use lib ".";
use main;
my $a = A.new(x => -1);
++$a;
but it naturally doesn't see ++ multi for A objects because main.rakumod doesn't know the *_ops.rakumod files as it stands. Is there a way I can achieve this? If I use prefix_ops in main.rakumod, it says 'use lib' may not be pre-compiled perhaps because of circular dependentness
it says 'use lib' may not be pre-compiled
The word "may" is ambiguous. Actually it cannot be precompiled.
The message would be better if it said something to the effect of "Don't put use lib in a module."
This has now been fixed per #codesections++'s comment below.
perhaps because of circular dependentness
No. use lib can only be used by the main program file, the one directly run by Rakudo.
Is there a way I can achieve this?
Here's one way.
We introduce a new file that's used by the other packages to eliminate the circularity. So now we have four files (I've rationalized the naming to stick to A or variants of it for the packages that contribute to the type A):
A-sawn.rakumod that's a role or class or similar:
unit role A-sawn;
Other packages that are to be separated out into their own files use the new "sawn" package and does or is it as appropriate:
use A-sawn;
unit class A-Ops does A-sawn;
multi prefix:<++>(A-sawn:D $obj) is export { ++($obj.x) }
multi postfix:<++>(A-sawn:D $obj) is export { ($obj.x)++ }
The A.rakumod file for the A type does the same thing. It also uses whatever other packages are to be pulled into the same A namespace; this will import symbols from it according to Raku's standard importing rules. And then relevant symbols are explicitly exported:
use A-sawn;
use A-Ops;
sub EXPORT { Map.new: OUTER:: .grep: /'fix:<'/ }
unit class A does A-sawn;
has $.x is rw;
Finally, with this setup in place, the main program can just use A;:
use lib '.';
use A;
my $a = A.new(x => -1);
say $a++; # A.new(x => -1)
say ++$a; # A.new(x => 1)
say ++$a; # A.new(x => 2)
The two main things here are:
Introducing an (empty) A-sawn package
This type eliminates circularity using the technique shown in #codesection's answer to Best Way to Resolve Circular Module Loading.
Raku culture has a fun generic term/meme for techniques that cut through circular problems: "circular saws". So I've used a -sawn suffix of the "sawn" typename as a convention when using this technique.[1]
Importing symbols into a package and then re-exporting them
This is done via sub EXPORT { Map.new: ... }.[2] See the doc for sub EXPORT.
The Map must contain a list of symbols (Pairs). For this case I've grepped through keys from the OUTER:: pseudopackage that refers to the symbol table of the lexical scope immediately outside the sub EXPORT the OUTER:: appears in. This is of course the lexical scope into which some symbols (for operators) have just been imported by the use Ops; statement. I then grep that symbol table for keys containing fix:<; this will catch all symbol keys with that string in their name (so infix:<..., prefix:<... etc.). Alter this code as needed to suit your needs.[3]
Footnotes
[1] As things stands this technique means coming up with a new name that's different from the one used by the consumer of the new type, one that won't conflict with any other packages. This suggests a suffix. I think -sawn is a reasonable choice for an unusual and distinctive and mnemonic suffix. That said, I imagine someone will eventually package this process up into a new language construct that does the work behind the scenes, generating the name and automating away the manual changes one has to make to packages with the shown technique.
[2] A critically important point is that, if a sub EXPORT is to do what you want, it must be placed outside the package definition to which it applies. And that in turn means it must be before a unit package declaration. And that in turn means any use statement relied on by that sub EXPORT must appear within the same or outer lexical scope. (This is explained in the doc but I think it bears summarizing here to try head off much head scratching because there's no error message if it's in the wrong place.)
[3] As with the circularity saw aspect discussed in footnote 1, I imagine someone will also eventually package up this import-and-export mechanism into a new construct, or, perhaps even better, an enhancement of Raku's built in use statement.
Hi #hanselmann here is how I would write this (in 3 files / same dir):
Define my class(es):
# MyClass.rakumod
unit module MyClass;
class A is export {
has $.x is rw;
}
Define my operators:
# Prefix_Ops.rakumod
unit module Prefix_Ops;
use MyClass;
multi prefix:<++>(A:D $obj) is export {
++$obj.x;
$obj;
}
Run my code:
# script.raku
use lib ".";
use MyClass;
use Prefix_Ops;
my $a = A.new(x => -1);
++$a;
say $a.x; #0
Taking my cue from the Module docs there are a couple of things I am doing different:
Avoiding the use of main (or Main, or MAIN) --- I am wary that MAIN is a reserved name and just want to keep clear of engaging any of that (cool) machinery
Bringing in the unit module declaration at the top of each 'rakumod' file ... it may be possible to use bare files in Raku ... but I have never tried this and would say that it is not obvious from the docs that it is even possible, or supported
Now since I wanted this to work first time you will note that I use the same file name and module name ... again it may be possible to do that differently (multiple modules in one file and so on) ... but I have not tried that either
Using the 'is export' trait where I want my script to be able to use these definitions ... as you will know from close study of the docs ;-) is that each module has it's own namespace (the "stash") and we need export to shove the exported definitions into the namespace of the script
As #raiph mentions you only need the script to define the module library location
Since you want your prefix multi to "know" about class A then you also need to use MyClass in the Prefix_Ops module
Anyway, all-in-all, I think that the raku module system exemplifies the unique combination of "easy things easy and hard thinks doable" ... all I had to do with your code (which was very close) was tweak a few filenames and sprinkle in some concise concepts like 'unit module' and 'is export' and it really does not look much different since raku keeps all the import/export machinery under the surface like the swan gliding over the river...

"python function decorator" for objective-c to change a method's behavior

I want to modify the behavior of some function without being the author of that function. What I control is that I can ask the author to follow some pattern, e.g. use a base class, use a certain decorator, property etc.
If in python, I would use a decorator to change the behavior of a method.
As an example, My goal: Improve code coverage by automatically testing over multiple input data.
Pseudo code:
#implementation SomeTestSuiteClass
// If in python, I would add a decorator here to change the behavior of the following method
-(void)testSample1 {
input = SpecialProvider();
output = FeatureToTest(input);
SpecialAssert(output);
}
#end
What I want: During test, the testSample1 method will be called multiple times. Each time, the SpecialProvider will emit a different input data. Same for the SpecialAssert, which can verify the output corresponding to the given input.
SpecialProvider and SpecialAssert will be API under my control/ownership (i.e. I write them).
The SomeTestSuiteClass together with the testSample1 will be written by the user (i.e. test writer).
Is there a way for Objective-C to achieve "what I want" above?
You could mock objects and/or its methods using objective-c runtime or some third party frameworks. I discourage it though. That is a sign of poor architecture choices in the 1st place. The main problem in your approach are hidden dependencies in your code directly referencing
SpecialProvider & SpecialAssert symbols directly.
A much better way to this would be like this:
-(void)testSample1:(SpecialProvider*)provider assert:(BOOL (^)(parameterTypes))assertBlock {
input = provider;
output = FeatureToTest(input);
if (assertBlock != nil) {
assertBlock(output);
}
}
Since Objective-c does not support default argument values like Swift does you could emulate it with:
-(void)testSample1 {
[self testSample1:DefaultSpecialProvider() assert:DefaultAssert()];
}
not to call the explicit -(void)testSample1:(SpecialProvider*)provider assert:(BOOL (^)(parameterTypes))assertBlock all the time, however in tests you would always use the explicit 2 argument variant to allow substituting the implementation(s) not being under test.
Further improvement idea:
Put the SpecialProvider and SpecialAssert behind protocols(i.e. equivalent of interfaces in other programming languages) so you can easily exchange the implementation.

Continuous improvement: Is it possible to specify the tests in advance?

I am used to "old fashioned" waterfall development cycles.
For a new project, continuous integration seems to better fit our need.
In waterfall, you have to specify the tests you will to implement in advance.
My questions:
What is the usual way with continuous integration development cycles regarding test specification?
If you don't specify the tests, can you imagine a way to specify them in advance?
Many thanks for your help.
At university we were taught that "test driven development" makes sense, especially if there is a proper coding specification.
If you're not able to write tests before coding -> the coding spec should be more specific / has issues.
I usually write unit-tests based on the coding spec for my java classes, which will afterwards be integrated and executed on our jenkins continuous integration server.
Forgive me if i am wrong but thats what i learned...
It always depends on the complexity of the required java classes, the trivial "domain" classes do not need a big specification info
In most cases we try to specify how the Classes or Methods should work (in words) and also write down the some example values.
Lets say you should write a method that should check if a value is in a specifig range:
// Example Specification:
// the method 'checkIfItsInRange' should return true when : the input lies within the range and it should be devidable by the distance value
// Lets say the range goes from -30,00 to +30,00 with a distance from 0,25
// valid values :30, -30, 15.25, 15.50, 17.75 etc. -> return true
// invalid : -31, -30.01, +30.08, 0.4 etc. -> return false
// MissingParameterException when one of the Parameters is null
public boolean checkIfItsInRange throws MissingParameterException (BigDecimal from, BigDecimal to, BigDecimal distance, BigDecimal input) {
// TODO implement depending on spec.
}
In this case you can already write some Unittests before you started to implement the method itself.
I hope that makes things a bit clearer.

How should I deal with external dependencies in my functions when writing unit tests?

The following function iterates through the names of directories in the file system, and if they are not in there already, adds these names as records to a database table. (Please note this question applies to most languages).
def find_new_dirs():
dirs_listed_in_db = get_dirs_in_db()
new_dirs = []
for dir in get_directories_in_our_path():
if dir not in dirs_listed_in_db:
new_dirs.append(dir)
return new_dirs
I want to write a unit test for this function. However, the function has a dependency on an external component - a database. So how should I write this test?
I assume I should 'mock out' the database. Does this mean I should take the function get_dirs_in_db as a parameter, like so?
def find_new_dirs(get_dirs_in_db):
dirs_listed_in_db = get_dirs_in_db()
new_dirs = []
for dir in get_directories_in_our_path():
if dir not in dirs_listed_in_db:
new_dirs.append(dir)
return new_dirs
Or possibly like so?
def find_new_dirs(db):
dirs_listed_in_db = db.get_dirs()
new_dirs = []
for dir in get_directories_in_our_path():
if dir not in dirs_listed_in_db:
new_dirs.append(dir)
return new_dirs
Or should I take a different approach?
Also, should I design my whole project this way from the start? Or should I refactor them to this design when the need arises when writing tests?
What you're describing is called dependency injection and yes, it is a common way of writing testable code. The second method you outlined (where you would pass in the db) is probably more common. Also, you can have the db parameter to your function take a default value so you are able to only specify the mock db in testing cases.
Whether to write your code that way at the outset or modify it later would be a matter of opinion, but if you adhere to the Test-driven development (TDD) methodology then you would write your tests before your code-under-test anyway.
There are other ways to deal with this problem, but you're asking a broad question at that point.
I take it these code fragments are python, which I'm not familiar with, but in any case this looks like the methods are detached from any stateful object and I'm not sure if that's idiomatic python or simply your design.
In an OOD you'd want an object that holds a data access object in its state (similar to your 2nd version) and mock that object for tests. You'd also want to mock the get_directories_our_path part.
As for when this design should be done - as the first step before creating the first code file. You should use dependency injection throughout your code. This will aid in testing as well as decoupling and increased reusability of your classes.

How do you USE Fortran 90 module data

Let's say you have a Fortran 90 module containing lots of variables, functions and subroutines. In your USE statement, which convention do you follow:
explicitly declare which variables/functions/subroutines you're using with the , only : syntax, such as USE [module_name], only : variable1, variable2, ...?
Insert a blanket USE [module_name]?
On the one hand, the only clause makes the code a bit more verbose. However, it forces you to repeat yourself in the code and if your module contains lots of variables/functions/subroutines, things begin to look unruly.
Here's an example:
module constants
implicit none
real, parameter :: PI=3.14
real, parameter :: E=2.71828183
integer, parameter :: answer=42
real, parameter :: earthRadiusMeters=6.38e6
end module constants
program test
! Option #1: blanket "use constants"
! use constants
! Option #2: Specify EACH variable you wish to use.
use constants, only : PI,E,answer,earthRadiusMeters
implicit none
write(6,*) "Hello world. Here are some constants:"
write(6,*) PI, &
E, &
answer, &
earthRadiusInMeters
end program test
Update
Hopefully someone says something like "Fortran? Just recode it in C#!" so I can down vote you.
Update
I like Tim Whitcomb's answer, which compares Fortran's USE modulename with Python's from modulename import *. A topic which has been on Stack Overflow before:
‘import module’ or ‘from module import’
In an answer, Mark Roddy mentioned:
don't use 'from module import *'. For
any reasonable large set of code, if
you 'import *' your will likely be
cementing it into the module, unable
to be removed. This is because it is
difficult to determine what items used
in the code are coming from 'module',
making it east to get to the point
where you think you don't use the
import anymore but its extremely
difficult to be sure.
What are good rules of thumb for python imports?
dbr's answer contains
don't do from x import * - it makes
your code very hard to understand, as
you cannot easily see where a method
came from (from x import *; from y
import *; my_func() - where is my_func
defined?)
So, I'm leaning towards a consensus of explicitly stating all the items I'm using in a module via
USE modulename, only : var1, var2, ...
And as Stefano Borini mentions,
[if] you have a module so large that you
feel compelled to add ONLY, it means
that your module is too big. Split it.
I used to just do use modulename - then, as my application grew, I found it more and more difficult to find the source to functions (without turning to grep) - some of the other code floating around the office still uses a one-subroutine-per-file, which has its own set of problems, but it makes it much easier to use a text editor to move through the code and quickly track down what you need.
After experiencing this, I've become a convert to using use...only whenever possible. I've also started picking up Python, and view it the same way as from modulename import *. There's a lot of great things that modules give you, but I prefer to keep my global namespace tightly controlled.
It's a matter of balance.
If you use only a few stuff from the module, it makes sense if you add ONLY, to clearly specify what you are using.
If you use a lot of stuff from the module, specifying ONLY will be followed by a lot of stuff, so it makes less sense. You are basically cherry-picking what you use, but the true fact is that you are dependent on that module as a whole.
However, in the end the best philosophy is this one: if you are concerned about namespace pollution, and you have a module so large that you feel compelled to add ONLY, it means that your module is too big. Split it.
Update: Fortran? just recode it in python ;)
Not exactly answering the question here, just throwing in another solution that I have found useful in some circumstances, if for whatever reason you don't want to split your module and start to get namespace clashes. You can use derived types to store several namespaces in one module.
If there is some logical grouping of the variables, you can create your own derived type for each group, store an instance of this type in the module and then you can import just the group that you happen to need.
Small example: We have a lot of data some of which is user input and some that is the result of miscellaneous initializations.
module basicdata
implicit none
! First the data types...
type input_data
integer :: a, b
end type input_data
type init_data
integer :: b, c
end type init_data
! ... then declare the data
type(input_data) :: input
type(init_data) :: init
end module basicdata
Now if a subroutine only uses data from init, you import just that:
subroutine doesstuff
use basicdata, only : init
...
q = init%b
end subroutine doesstuff
This is definitely not a universally applicable solution, you get some extra verbosity from the derived type syntax and then it will of course barely help if your module is not the basicdata sort above, but instead more of a allthestuffivebeenmeaningtosortoutvariety. Anyway, I have had some luck in getting code that fits easier into the brain this way.
The main advantage of USE, ONLY for me is that it avoids polluting my global namespace with stuff I don't need.
Agreed with most answers previously given, use ..., only: ... is the way to go, use types when it makes sense, apply python thinking as much as possible. Another suggestion is to use appropriate naming conventions in your imported module, along with private / public statements.
For instance, the netcdf library uses nf90_<some name>, which limits the namespace pollution on the importer side.
use netcdf ! imported names are prefixed with "nf90_"
nf90_open(...)
nf90_create(...)
nf90_get_var(...)
nf90_close(...)
similarly, the ncio wrapper to this library uses nc_<some name> (nc_read, nc_write...).
Importantly, with such designs where use: ..., only: ... is made less relevant, you'd better control the namespace of the imported module by setting appropriate private / public attributes in the header, so that a quick look at it will be sufficient for readers to assess which level of "pollution" they are facing. This is basically the same as use ..., only: ..., but on the imported module side - thus to be written only once, not at each import).
One more thing: as far as object-orientation and python are concerned, a difference in my view is that fortran does not really encourage type-bound procedures, in part because it is a relatively new standard (e.g. not compatible with a number of tools, and less rationally, it is just unusual) and because it breaks handy behavior such as procedure-free derived type copy (type(mytype) :: t1, t2 and t2 = t1). That means you often have to import the type and all would-be type-bound procedures, instead of just the class. This alone makes fortran code more verbose compared to python, and practical solutions like a prefix naming convention may come in handy.
IMO, the bottom line is: choose your coding style for people who will read it (this includes your later self), as taught by python. The best is the more verbose use ..., only: ... at each import, but in some cases a simple naming convention will do it (if you are disciplined enough...).
Yes, please use use module, only: .... For large code bases with multiple programmers, it makes the code easier to follow by everyone (or just use grep).
Please do not use include, use a smaller module for that instead. Include is a text insert of source code which is not checked by the compiler at the same level as use module, see: FORTRAN: Difference between INCLUDE and modules. Include generally makes it harder for both humans and computer to use the code which means it should not be used. Ex. from mpi-forum: "The use of the mpif.h include file is strongly discouraged and may be deprecated in a future version of MPI." (http://mpi-forum.org/docs/mpi-3.1/mpi31-report/node411.htm).
I know I'm a little late to the party, but if you're only after a set of constants and not necessarily computed values, you could do like C and create an include file:
inside a file,
e.g., constants.for
real, parameter :: pi = 3.14
real, parameter :: g = 6.67384e-11
...
program main
use module1, only : func1, subroutine1, func2
implicit none
include 'constants.for'
...
end program main
Edited to remove "real(4)" as some think it is bad practice.