Skip to content

A class imported through package import is not equal to the same class imported with relative path #23788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
emilniklas opened this issue Jul 5, 2015 · 3 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-as-intended Closed as the reported issue is expected behavior

Comments

@emilniklas
Copy link

// lib/my_library.dart
library my_library;

class MyClass {}
// lib/a.dart
import 'my_library.dart';

compare(Type type) => type == MyClass;
// main.dart
import 'package:my_library/my_library.dart'; // importing MyClass
import 'lib/a.dart'; // importing compare, which imports MyClass

main() {
  print(MyClass == MyClass); // true
  print(compare(MyClass)); // false
}

Whereas importing both a.dart and my_library.dart as a package: URI, or as a relative path, results in both statements printing true:

// main.dart
import 'lib/my_library.dart'; // importing MyClass
import 'lib/a.dart'; // importing compare, which imports MyClass

main() {
  print(MyClass == MyClass); // true
  print(compare(MyClass)); // true
}
// main.dart
import 'package:my_library/my_library.dart'; // importing MyClass
import 'package:my_library/a.dart'; // importing compare, which imports MyClass

main() {
  print(MyClass == MyClass); // true
  print(compare(MyClass)); // true
}

If I want to interact with a type within a library, but I send the type I want to interact with from outside the library, even though the type is declared within the library, strange inequalities results in weird behaviour.

@emilniklas emilniklas changed the title A class imported through package import is not equal to the same class imported directly A class imported through package import is not equal to the same class imported with relative path Jul 5, 2015
@lrhn lrhn added area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-as-intended Closed as the reported issue is expected behavior labels Jul 6, 2015
@lrhn
Copy link
Member

lrhn commented Jul 6, 2015

That is the expected behavior. A library is identified by the URI used to point to it (after resolution and nomalization).
If you use two different URIs to import what ends up being the same file, it's still treated as two different libraries, each defining its own version of the class. You should get a warning because you have imported two libraries with the same name, which is a good way to detect this problem.

The solution here is to always refer to a package library using a package:-URI (except inside the package's lib/ directory itself). Or, in other words, never ever write "lib/" as part of an import.

@lrhn lrhn closed this as completed Jul 6, 2015
@emilniklas
Copy link
Author

I see. However, in my case, the package has multiple libraries. Like so:

lib/
  a.dart // is library
  b.dart // is another library that imports a
c.dart // outside library, imports both a and b, and want them to agree on classes

That means, to make sure b and c identifies classes in a as equal, b must import a with a package: URI. Even though they are in the same package (share lib directory).

It's not really a problem, but it seems the convention to only use package: from the outside of a package might result in unexpected behaviour.

Shouldn't the convention then be: ALWAYS use package: when importing public libraries, and ONLY use relative path when it is private to the package ?

@lrhn
Copy link
Member

lrhn commented Jul 8, 2015

If you always import package libraries (this in the lib/ dir of a package) using a package: URI from any other place, then it's ok for the libraries in a lib/ dir to refer to each other using relative paths. The relative path will be resolved against the library's own URI, which will then always be a package: URI, and all is well.

What usually goes wrong is that you refer to a library in a lib/ dir directly from somewhere in the same package (in test/ or in bin/ perhaps), or even that you run one of them directly as a script. Being in the same package structure is not enough, it's being in the same lib/ dir that's the rule for when you can use relative references.
Using a package: URI to refer to a different file in the same lib/ dir will not prevent a problem - using a relative path is only a problem if the importing library was imported improperly, so you already have a problem that should be fixed. If anything, getting an error is a good way to catch that problem (but so should duplicate library name warnings).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-as-intended Closed as the reported issue is expected behavior
Projects
None yet
Development

No branches or pull requests

2 participants