I want to build up a tests library and keep it separated from the libraries under development. My first thought is to go for a structure like the following:
PensLib
--Variants
----BallPoint
----FountainPen
----Tests
------TB_BallPoint
HammocksLib
--Variants
----SingleHammock
----DoubleHammock
----Tests
------TB_DoubleHammock
--Systems
----IndoorWalls
----OutdoorWallAndTree
----CoconutPalms
----Tests
------TB_IndoorWalls
Tests
--PensLib
----Variants
------Test_BallPoint // extends PensLib.Variants.Tests.TB_BallPoint
--HammocksLib
----Variants
------Test_DoubleHammock // extends HammocksLib.Variants.Tests.TB_DoubleHammock
----Systems
------Test_IndoorWalls // extends HammocksLib.Systems.Tests.TB_IndoorWalls
For now let's assume that the way I structure my libraries make sense (which most likely doesn't). I will soon ask more questions on good practices in setting up the testing environment in Dymola and with the Testing Library.
My question is about the correct way to handle relative and absolute paths within models, if possible at all.
The model PensLib.Variants.Tests.TB_BallPoint is used for developing the variant BallPoint
The model Tests.PensLib.Variants.Tests_BallPoint is used for automated testing
I want the model Test_BallPoint to extend the model TB_BallPoint, but I cannot link them. I guess the absolute path PensLib.Variants.Tests.TB_BallPoint is treated as a relative one, since PensLib is found "on the way out" of the Tests library, and from there it goes looking for the rest of the path. Is there perhaps a way to control the path, kind of ..\..\..\PensLib\Variants\Tests\TB_BallPoint?
As you already noted such a setup makes troubles. There are ways around that, namely global name lookup and imports, which I explain briefly further below.
Both solutions are nice when you have such a case in a few situations. But if you have to use it all the time, you make your setup unnecessarily complicated.
Hence, I suggest to make yourself the live easier and change your package structure:
Either create a dedicated test library for every library, maybe PensLib_Tests and HammocksLib_Tests
Or rename the packages in the Tests library and don't use the exact library names
Global name lookup
You can use absolute class paths. They are denoted with a leading ., so this should work:
extends .PensLib.Variants.Tests.TB_BallPoint;
See Modelica Specification chapter 5: Scoping, Name Lookup, and Flattening for details, especially 5.3.3 Global Name Lookup
Importing
You can simply import the library. Lookup of imports is always performed globally.
import PensLib;
extends PensLib.Variants.Tests.TB_BallPoint;
Related
Erlang's -import() directive lets you import code from other modules. Its include() directive lets you import code from headers. Why reasons are there to prefer either one over the other?
My hunch is that headers are good for short, easy-on-the-compiler kinds of code, such as record definitions, when you don't want to have to qualify the
Learn You Some Erlang states[1] that "Erlang header files are pretty similar to their C counter-part: they're nothing but a snippet of code that gets added to the module as if it were written there in the first place." Thus inclusion seems to cause the compiler to duplicate effort across different modules. And header files are what appear to be an optional complication on top of the mandatory module system. So why would I ever use a header file?
[1] https://learnyousomeerlang.com/a-short-visit-to-common-data-structures
Erlang's -import just allows you to call imported functions without the Module. It hurts legibility and should not be used: You need to check the import directive to know whether a function is local or external to the module.
With header files you get the same functionality as in C, you can use them to share -record definitions instead of having a dto-like module (1), you can use them to include -defines to use the same macros (2).
1:
-record(position, {x, y}).
Imagine that you have #position{} throughout the code, instead of defining the record everywhere and updating all of the copies when the record definition changes, you use a header (or a dto module with opaque types, but that's for another question).
And let's just hope that you remember to update all the copies, otherwise chaos ensues.
2:
-define(ENUM01, enum01).
-define(DEFAULT_TIMEOUT, 1000).
Instead of using enum01 and 1000 everywhere, which is error prone and requires multiple updates if you need to change them, you define them in a header and use them as ?ENUM01 and ?DEFAULT_TIMEOUT
Or you can be more thorough when testing:
-ifdef(TEST).
-define(assert(A), true = A).
-else
-define(assert(A), A).
-endif.
Or you can include some useful information:
-define(LOG(Level, X), logger:log(Level, X, #{line => ?LINE}).
The Erlang standard library uses header files to provide the ability to add metadata to your code.
For instance, EUnit functionality:
-include_lib("eunit/include/eunit.hrl").
import is helpful in building encapsulations, whereas include is kind of pre-processing(which means code will be part of the unit before it gets through the compiler).
An import ensues a dependency between two modules, which means a module A importing module B has B as dependency ... Whereas an include is extensional which means a module has included some code and that code is part of the module itself, and that is what header files do.
module(s) and header(s) are 2 semantically different things and serve different purposes. With modules, we can build abstractions by using the export(s), keep things confined by not exporting them, import from other modules(but they are not exported by default), re-export imported things etc etc. So when we import stuff, we can call upon functions from the other module, but only those which are exported in the other module. However that is not the case with header files. Everything inside a header file becomes part of the module which includes them. There is no sense of export/import inside header files. And header files are quite useful for writing and distributing definition(s) which otherwise could lead to redundancy in case of large programs.
So essentially they are 2 different things, so 2 different keywords available at our disposal. So don't prefer one over the other. Learn both of them as we need both of them.
In Flutter, for importing libraries within our own package's lib directory, should we use relative imports
import 'foo.dart'
or package import?
import 'package:my_app/lib/src/foo.dart'
Dart guidelines advocate to use relative imports :
PREFER relative paths when importing libraries within your own package’s lib directory.
whereas Provider package says to always use packages imports :
Always use package imports. Ex: import 'package:my_app/my_code.dart';
Is there a difference other than conciseness? Why would packages imports would reduce errors over relative imports?
From the same Dart guidelines, further down they give this reason for the relative imports:
There is no profound reason to prefer the former—it’s just shorter, and we want to be consistent.
Personally, I prefer the absolute method, despite it being more verbose, as it means when I'm importing from different dart files (in other folders), I don't have to work out where the file to be imported is, relative to the current file. Made-up example:
I have two dart files, at different folder levels, that need to import themes/style.dart:
One is widgets/animation/box_anim.dart, where the relative path import would be:
import '../../themes/style.dart';
The other is screens/home_screen.dart with the relative import:
import '../themes/style.dart';
This can get confusing, so I find it better to just use the absolute in both files, keeping it consistent:
import 'package:myapp/themes/style.dart';
And just stick that rule throughout. So, basically, whatever method you use - Consistency is key!
The Linter for Dart package, also has something to say about this, but is more about the Don'ts of mixing in the '/lib' folder:
DO avoid relative imports for files in lib/.
When mixing relative and absolute imports it's possible to create
confusion where the same member gets imported in two different ways.
An easy way to avoid that is to ensure you have no relative imports
that include lib/ in their paths.
TLDR; Choose the one you prefer, note that prefer_relative_imports is recommended in official Effective Dart guide
First of all, as mentioned in this answer, Provider do not recommands package imports anymore.
Dart linter provides a list of rules, including some predefined rulesets :
pedantic for rules enforced internally at Google
lints or even flutter_lints (previously effective_dart) for rules corresponding to the Effective Dart style guide
flutter for rules used in flutter analyze
Imports rules
There is actually more than two opposites rules concerning imports :
avoid_relative_lib_imports, enabled in pedantic and lints rulesets, basically recommend to avoid imports that have 'lib' in their paths.
The two following are the one you mention :
prefer_relative_imports, enabled in no predefined rulesets, but recommended in Effective Dart guide in opposition to :
always_use_package_imports, enabled in no predefined rulesets. Which means that it is up to you and to your preferences to enable it (be careful, it is incompatible with the previous rule)
Which one should I choose?
Choose the rule you want ! It will not cause any performance issue, and no rule would reduce errors over the other. Just pick one and make your imports consistent across all your project, thanks to Dart linter.
I personnaly prefer using prefer_relative_imports, as it is recommended by Dart team, with this VSCode extension which automatically fix and sort my imports.
Provider do not need packages imports anymore.
This was a workaround to an old Dart bug: Flutter: Retrieving top-level state from child returns null
TL;DR, by mixing relative and absolute imports, sometimes Dart created a duplicate of the class definition.
This led to the absurd line that is:
import 'package:myApp/test.dart' as absolute;
import './test.dart' as relative;
void main() {
print(relative.Test().runtimeType == absolute.Test().runtimeType); // false
}
Since provider relies on runtimeType to resolve objects, then this bug made provider unable to obtain an object in some situations.
My 5 cents on the topic are that absolute (package:my_app/etc/etc2...) imports cause much less trouble than relative ones (../../etc/etc2...) when you decide to reorganize/cleanup your project`s structure because whenever you move a file from one directory to another you change the "starting point" of every relative import that this file uses thus breaking all the relative imports inside the moved file...
I'd personally always prefer absolute to relative paths for this reason
This question already has good answers, but I wanted to mention an insanely annoying and hard-to-find problem I experienced with unit testing that was caused by a relative import.
The expect fail indicator for an exception-catching expect block
expect(
() => myFunction,
throwsA(isA<InvalidUserDataException>())
);
was showing the actual result as exactly the same as the expected result, and zero indication of why it's failing.
After massive trial-and-error, the issue was because the expected InvalidUserDataException (a custom-made class) was being imported to the test file in RELATIVE format vs PACKAGE format.
To find this, I had to compare side-by-side, line-by-line, call-by-call between this test file and another test file that uses the exact same exception expecters (It's lucky, we had this), and just by chance, I happened to scroll to the top of this file's imports and see the blue underline saying prefer relative imports to /lib directory.
No, they're not preferred; they're necessary, because the moment I changed that to a PACKAGE (absolute) import, everything suddenly started working.
What I learned from this is: Use absolute imports for test files (files outside the lib directory)
e.g. inside of src/test/main_test.dart
DON'T: use import '../lib/main.dart'
DO: use package:my_flutter_app/main.dart
Maybe other people knew this already, but I didn't, and I couldn't find anything online with searches about this issue, so I thought I would share my experience that might help others who got stuck around this.
Does anyone know why this happens?
Edit: For context, this happened while using Flutter 2.1.4 (stable) with Sound Null Safety
Do you use Integration Tests?
If the answer is yes, then in most cases you need to use package imports. When you attempt to run your integration tests on a physical device, any relative imports will not be able to find what they're looking for.
Example: https://github.com/fluttercommunity/get_it/issues/76
You can enforce package imports in your project by using these two linting rules:
always_use_package_imports
avoid_relative_lib_imports
I also prefer package imports because they stick even when rearranging your files and folders. Relative imports frequently break and it's a pain to have to remove them and reimport the offending dependency.
One very simple reason to not use package imports: rename your package without editing every dart file
Renaming can happen a few times while the product does not have a definitive name, and you or your product owner decides to change it.
It is much more painful to rename with package imports as your package name is in every import.
Of course you can change it with a find/replace query, but it's a useless edit on every dart file you can avoid with relative imports.
Plus, vscode allows to automatically update relative imports on file move/rename and I have never had any issue with this feature.
Now I have some experience in using the Zend Framework. I want to go deeper in the topic and rewrite some old php projects.
What is the best place to save own functions and classes?
And how do I tell Zend where they are? Or is there already a folder for own stuff? May I have different folders for different files?
For example I want to save a php document with the name math_b.php which includes several special functions to calculate and another one date_b.php which has abilities for datetime stuff. Is that possible or shall I have different files for every function?
I would also like to reuse the functions in other projects and then just copy the folders.
There is no single "right" answer for this. However, there are several general guidelines/principles that I commonly employ.
Do not pollute global scope
Namespace your code and keep all functions is classes. So, rather than:
function myFunction($x) {
// do stuff with $x and return a value
}
I would have:
namespace MyVendorName\SomeComponent;
class SomeUtils
{
public static function myFunction($x)
{
// do stuff with $x and return a value
}
}
Usage is then:
use MyVendorName\SomeComponent\SomeUtils;
$val = SomeUtils::myFunction($x);
Why bother with all this? Without this kind of namespacing, as you bring more code into your projects from other sources - and as you share/publish your code for others to consume in their projects - you will eventually encounter name conflicts between their functions/variables and yours. Good fences make good neighbors.
Use an autoloader
The old days of having tons of:
require '/path/to/class.php';
in your consumer code are long gone. A better approach is to tell PHP - typically during some bootstrap process - where to find the class MyVendor\MyComponent\MyClass. This process is called autoloading.
Most code these days conforms to the PSR-0/PSR-4 standard that maps name-spaced classnames to file-paths relative to a file root.
In ZF1, one typically adds the ./library folder to the PHP include_path in ./public/index.php and then add your vendor namespace into the autoloaderNameSpaces array in ./application/config.ini:
autoloaderNameSpaces[] = 'MyVendor';
and places a class like MyVendor\MyComponent\MyClass in the file:
./library/MyVendor/MyComponent/MyClass.php
You can then reference a class of the form MyVendor\MyComponent\MyClass simply with:
// At top of consuming file
use MyVendor\MyComponent\MyClass;
// In the consuming page/script/class.
$instance = new MyClass(); // instantiation
$val = MyClass::myStaticMethod(); // static method call
Determine the scope of usage
If I have functionality is required only for a particular class, then I keep that function as a method (or a collection of methods) in the class in which it is used.
If I have some functionality that will be consumed in multiple places in a single project, then I might break it out into a single class in my own library namespace, perhaps MyVendor.
If I think that a function/class will be consumed by multiple projects, then I break it out into its own project with its own repo (on Github, for example), make it accessible via Composer, optimally registering it with Packagist, and pay close attention to semantic versioning so that consumers of my package receive a stable and predictable product.
Copying folders from one project into another is do-able, of course, but it often runs into problems as you fix bugs, add functionality, and (sometimes) break backward-compatibility. That's why it is usually preferable to have those functions/classes in a separate, semantically-versioned project that serves as a single source-of-truth for that code.
Conclusion
Breaking functionality out into separate, namespaced classes that are autoloaded in a standard way gives plenty of "space" in which to develop custom functionality that is more easily consumed, more easily re-used, and more easily tested (a large topic for another time).
In SugarCRM, you can create your custom modules (e.g. MyModule) and they are kept in /modules just like stock objects, with any default metadata, views, language files, etc. For a custom module MyModule, you might have something like:
/modules/MyModule/MyModule.class.php
/modules/MyModule/MyModule.php
/modules/MyModule/language/
/modules/MyModule/metadata
And so on, so that everything is nicely defined and all the modules are kept together. The module becomes registered with the system by a file such as /custom/Extension/application/Include/MyModule.php with contents something like:
<?php
$beanList['MyModule'] = 'MyModule';
$beanFiles['MyModule'] = 'modules/MyModule/MyModule.php';
$moduleList[] = 'MyModule';
Obviously, the $beanFiles array references where we can find the base module's class, usually an extension of the SugarBean object. Recently I was advised that we can adjust that file's location for the sake of customization, and it makes sense to a degree. Setting it like $beanFiles['MyModule'] = 'custom/modules/MyModule/MyModule.php'; would allow us to access the base class via Module Loader even if the security scan tool prevents core file changes, and this would also allow us to not exactly extend, but replace stock modules like Accounts or Calls, without modifying core files and having system upgrades to wipe out the changes.
So here's my question: what is the best practice here? I've been working with SugarCRM pretty intensely for several years and this is the first time I've ever been tempted to modify the $beanFiles array. My concern is that I'm deviating from best practice here, and also that somehow both files modules/MyModule/MyModule.php and custom/modules/MyModule/MyModule.php could be loaded which would cause a class name conflict in PHP (i.e. because both classes are named MyModule...). Obviously, any references to the class would need to be updated (e.g. an entryPoint that works with this module), but am I missing any potential ramifications?
Technically it should be fine, but I can see how it could be possible that both the core version and your version could conflict if both are referenced. It all depends on the scenario, but I prefer to extend the core bean and find somewhere in the stack where I can have my custom version used in place of the core bean. I wrote up an example a couple of years ago here: https://www.sugaroutfitters.com/blog/safely-customizing-a-core-bean-in-sugarcrm
For most use-cases, there's a way to hijack Sugar to use your bean at a given point.
If you can't get around it you can always grep to see where the core module is explicitly being included to ensure that there won't be conflict down the road.
I've done some searching on this, but I cannot find info. I'm building an application inside sinatra, and using the coffeescript templating engine. By default the compiled code is wrapped as such:
(function() {
// code
}).call(this);
I'd like to remove that using the --bare flag, so different files can access classes and so forth that I'm defining. I realize that having it more contained helps against variable conflicts and so forth, but I'm working on two main pieces here. One is the business logic, and arrangement of data in class structures. The other is the view functionality using raphaeljs. I would prefer to keep these two pieces in separate files. Since the two files wrapped as such cannot access the data, it obviously won't work. However, if you can think of a better solution than using the --bare option, I'm all ears.
Bare compilation is simply a bad practice. Each file should export to the global scope only the public objects that matter to the rest of your app.
# foo.coffee
class Foo
constructor: (#abc) ->
privateVar = 123
window.Foo = Foo # export
Foo is now globally available. Now if that pattern isn't practical, maybe you should rethink your structure a bit. If you have to export too may things, you nest and namespace things better, so that more data can be exposed through fewer global variables.
I support Alex's answer, but if you absolutely must do this, I believe my answer to the same question for Rails 3.1 is applicable here as well: Put the line
Tilt::CoffeeScriptTemplate.default_bare = true
somewhere in your application.