What Does :Global (Colon Global) Do

TCL global variable vs double colon variable

If this is in a procedure, there's no functional difference to what variable gets set or what value gets put in it. (global has no effect outside of procedures, and other things with local variable tables such as lambdas and methods.)

Where there is an actual difference is in exactly how things are done. In particular, global sets things up once so that future unqualified variable accesses are fast, whereas using the qualified form always does a full lookup (which may involve multiple hash table accesses). The effect is such that while a single read or write is quicker with fully qualified form, multiple accesses are always quicker if done with global (and the effect becomes a bit stronger with multiple variables in the global call, as some of the costs are amortisable).

But don't take my word for it. Make some sample procedures and test for yourself with time, perhaps like this:

proc write1 {} {
global MyVar
set MyVar 5
return
}
proc write2 {} {
global MyVar
set MyVar 5
set MyVar 5
return
}
proc write3 {} {
global MyVar MyOtherVar
set MyVar 5
set MyOtherVar 5
return
}
proc write4 {} {
global MyVar MyOtherVar
set MyVar 5
set MyOtherVar 5
set MyVar 5
set MyOtherVar 5
return
}
proc write5 {} {
set ::MyVar 5
return
}
proc write6 {} {
set ::MyVar 5
set ::MyVar 5
return
}
proc write7 {} {
set ::MyVar 5
set ::MyOtherVar 5
return
}
proc write8 {} {
set ::MyVar 5
set ::MyOtherVar 5
set ::MyVar 5
set ::MyOtherVar 5
return
}

foreach cmd {write1 write2 write3 write4 write5 write6 write7 write8} {
# Execute once to ensure everything is internally optimised
$cmd
# Now the timing run
puts "$cmd : [time { $cmd } 100000]"
}

On my laptop (quite a few years old now) running Tcl 8.6.9, I get this:


write1 : 0.62610808 microseconds per iteration
write2 : 0.63969525 microseconds per iteration
write3 : 0.73437284 microseconds per iteration
write4 : 0.7519245699999999 microseconds per iteration
write5 : 0.62230006 microseconds per iteration
write6 : 0.8437912799999999 microseconds per iteration
write7 : 0.8246234299999999 microseconds per iteration
write8 : 1.2297289900000001 microseconds per iteration

As you can see (and confirm for yourself on your own hardware), write1 is slower than write5, but for each of the other pairs, using global is a performance win. (I'm a little surprised that write3 beats write7, but the figures don't lie.)

differences between double colon and global variables use?

They're talking about the same variable. With the ::var form, you're using the fully-qualified name, whereas with the form with global you're making a local link to the global variable (which really is a pointer to the global variable). Reading from or writing to them should work exactly the same, whichever way you choose.

There is a measurable difference between the two. With global, you've got the extra cost of setting up the link, but thereafter for the remainder of the procedure the cost per use (read or write) is quite a lot lower. With the other form, you're not paying any setup overhead, but the per-use cost is higher. For one use only, the cost of the two are pretty similar. If you're using the variable several times, global is cheaper. OTOH, sometimes it is clearer to use the fully qualified version anyway (particularly true with vwait and trace) despite the reduction in speed.

I find that I access the ::env and ::tcl_platform arrays using their fully-qualified form, but most other things will get accessed via global. That's just my preference though.


Here's an example interactive session:

% set x 1
1
% proc y1 {} {incr ::x;return ok}
% time { y1 } 10000
0.5398216 microseconds per iteration
% proc y2 {} {global x;incr x;return ok}
% time { y2 } 10000
0.4537753 microseconds per iteration
% proc z1 {} {return $::x}
% time { z1 } 10000
0.4864713 microseconds per iteration
% proc z2 {} {global x; return $x}
% time { z2 } 10000
0.4433554 microseconds per iteration

(I wouldn't expect you to get the same absolute figures as me. Do your own performance testing. I would expect similar relative figures…)

React global SCSS: class styling not working

Are you using css-modules?

In that case, css-modules adds a hash at the end of the class name. You can avoid it by switching to the global scope for your class.

:global {
.marginsContainer {
width: 90%;
margin: auto;
padding: 100px;
}
}

A better solution is to use the class name with the hash, by importing the stylesheet like this.

import styles from '../global-styles/main.scss';

And setting the class name like this.

<div className={styles.marginsContainer}>

Issue with :global() css-module selectors not being pure in NextJS

No there isn't any solution as of yet other than overriding the webpack config itself. It was working in CRA because they probably have mode: local, while Next.js has pure.


I haven't tried overriding css-loader webpack config, so I am simply suggesting a workaround. Since, you are using SCSS, you can wrap your pseudo-global [1] styles like this:

.root :global {
.foo {
color: red;
}
}

Now wrap your component/page in a div and set the class as styles.root on that element. Then, on all the child elements you can directly set className="foo".

import styles from "../styles/index.module.scss";

const IndexPage = () => (
<div className={styles.root}>
<div className="foo">This text should be red!</div>
</div>
);

export default IndexPage;

Note that, you need to consider issues regarding specificity after this method, also this doesn't directly work with animations, you need to separate the keyframes and then make them global.

Demo Sandbox


[1]: This method doesn't make the styles truly global as the styles are still scoped. The class foo will work only when some parent has styles.root as class. This is preferrable only if you didn't intend to use your :global(.selector) from other components, and were using them just because you wanted to manipulate the class names using JS without the styles object.

If you want these to be truly global, add styles.root to document.documentElement in an useEffect hook like this:

import { useEffect } from "react";
import styles from "../styles/index.module.scss";

const IndexPage = () => {
useEffect(() => {
document.documentElement.classList.add(styles.root);
return () => {
document.documentElement.classList.remove(styles.root);
};
}, []);

return (
<div className="foo">
This text should be red, even if you put it in another component until the
page is same. If you want it across pages inject it in _app or _document.
</div>
);
};

export default IndexPage;

Demo Sandbox

PS: Injecting class to html in _app or _document is not exactly same as using a global stylesheet, as it may happen that you have multi-page application, then only the CSS of the components on a particular page will be requested because of automatic CSS code-splitting done by Next.js. If that's not the case and all your pages share same CSS, then there is no need to complicate things, just go with the conventional method of importing styles in _app.

What does a double colon do inside a module?

It's a scope modifier. Prefixing your constant (Tag) with a double colon ensures that you're looking in the root/global namespace instead of within your current module.

E.g.

module Foo
class Bar
def self.greet
"Hello from the Foo::Bar class"
end
end

class Baz
def self.scope_test
Bar.greet # Resolves to the Bar class within the Foo module.
::Bar.greet # Resolves to the global Bar class.
end
end
end

class Bar
def self.greet
"Hello from the Bar class"
end
end

The prepending is usually not neccessary as Ruby automatically looks in the global namespace, if it fails to find the referenced constant in the local module. So if no Bar existed in the Foo module, then Bar.greet and ::Bar.greet would do the exact same thing.

Selector :global .class is not pure (pure selectors must contain at least one local class or id)

You need to use global selector inside your local selector in CSS-modules.

For example, if you have HTML:

<div className={classes.someCSSMoludesClass}>
<div className="some-global-class">
content
</div>
</div>

for rewriting global class "some-global-class" you need to make this inside your CSS-module:

.someCSSModulesClass {
:global(.some-global-class) {
%your properties%
}
}

Don't forget to use selector inside :global.

I had the same problem, but in swiper slider, and resolved it like this.
Maybe you have to write this class in the component that is above

Why function that refers to a global function in the same section can only be solved at link time while local functions will be solve at compile time?

The assembler can solve jumping/calling myGlobalFunction defined in the same section at asm-time, and sometimes it does so, as Peter Cordes investigated.
However, as the function is declared global, it is assumed to be available from other sections, too.

Assembler thinks that your .text section from the file prog.o might be statically linkable to other programs at link-time. You are right that in such case other.o declares myGlobalFunction as external, the relocation record should be generated into other.o, and relocation of call myGlobalFunction in prog.o is superabundant. Perhaps clang.exe assumes that the symbol myGlobalFunction is potentially weak and that it could be replaced at link-time with homonymous global symbol defined in someother.o, also linked together with other.o and prog.o.

Call of a global function in the same section could be resolved at compile time. My guess is that Clang defers this to link-time and generates RIP-relative relocation to enable future replacement of the target function from other module.



Related Topics



Leave a reply



Submit