question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Read-only variables for used modules

See original GitHub issue

Currently, built-in modules and userland modules have a big difference (which is not clearly explained in the doc IMO): in userland modules, any exported variable is writable by downstream modules, and this impacts other modules importing the same module later. This is even true for variables that are not configurable in @use. On the other hand, variables exported by built-in modules (math.$pi for instance) are immutable.

To me, this behavior of builtin modules makes it harder to reason about the behavior of modules, as I cannot look only at upstream modules to find out where a value comes from.

This behavior also makes variables unsuitable for cases where downstream modules are not meant to be allowed to change the values (for instance a color palette of a design system, where downstream modules should only be allowed to use colors).

Reproducing case proving this
// _a.scss
$v: "a";
@debug $v;
// _b.scss
@use "a";

@debug a.$v;
// _c.scss
@use "a" as c;

c.$v: "b";
@debug c.$v;
// b_first.scss
@use "b";
@use "c";
// c_first.scss
@use "c";
@use "b";

Output for sass b_first.scss:

_a.scss:2 Debug: a
_b.scss:3 Debug: a
_c.scss:4 Debug: b

Output for sass c_first.scss:

_a.scss:2 Debug: a
_c.scss:4 Debug: b
_b.scss:3 Debug: b

As you can see, the file in _c.scss (that knows nothing about _b.scss) will get a different in the value it receives from _a.scss depending on the order in which modules gets executed for the first time, which can only be determined by looking at the whole dependency graph starting at the entrypoint (and things are even worse if meta.loadCss adds some module execution in places that cannot be found statically).

Being able to expose values that can be read is nice API for anything needing to expose reusable values IMO (and math.$e is a good proof of it). But most cases I can think about don’t actually expect those members to be writable in downstream modules. https://github.com/Awjin/guten-type/blob/master/src/_config.scss is another case that seems to prove it, using functions to expose members in a read-only way instead of exposing them directly.

Is it expected to make those members writable (the implementation seems to say yes, as I don’t see how that could have been implemented by accident) ? And do you think there should be a way for modules to forbid downstream assignments ?

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:2
  • Comments:8 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
stofcommented, Oct 26, 2021

@Awjin the question is also whether authors (not belonging to the Sass core team) realize that exported variables are writable. Last time I checked, the documentation about Sass modules was not telling anything about that (and the emphasis about configuring modules might make them think that those variables are indeed writable only through the configuration, which is why I thought myself until I started reading the code of dart-sass to discover the opposite)

0reactions
stofcommented, Nov 2, 2021

@AprilArcus styles are compiled on the module execution, the first time it is used. So any module variable re-assignment will not affect the module styles. But it will affect the module API used by other modules (the value of the exported variable, the output of the exported functions/mixins if they use that variable, etc…)

Read more comments on GitHub >

github_iconTop Results From Across the Web

Making C module variables accessible as read-only
Is there a best way to make variables modified in a module accessible as read-only in other modules? Best in what aspect?
Read more >
ReadOnly - Visual Basic
Specifies that a variable or property can be read but not written. Remarks. Rules. Declaration Context. You can use ReadOnly only at module...
Read more >
Readonly - Facility for creating read-only scalars, arrays, ...
Description. This is a facility for creating non-modifiable variables. This is useful for configuration files, headers, etc.
Read more >
How to create readonly constant variables
Import the Immutable Constant Example channel from the Interfaceware Support repository. Review the main.lua and see how ConstantConfigs module is used in the ......
Read more >
Making a read-only attribute
If you need to make a read-only attribute in Python, you can turn your attribute into a property that delegates to an attribute...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found