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
Disable/Turn Off Inherited CSS3 Transitions
Responsive Canvas in Bootstrap Column
CSS Grid: Content to Use Free Space But Scroll When Bigger
Including Margin for Width and Height
Svg @Font-Face Works in Svg But Not When Included in a Page
(Css) Eliminating Browser's 'Selected' Lines Around a Hyperlinked Image
Internet Explorer Button:Active Inner-Padding
CSS Transition When Class Removed
Css: Display: Grid And/Or -Ms-Grid
Is There Any Difference Between "Margin: 0 Auto;" and "Margin: Auto;"
How to Exclude a Specific Element from Inheriting CSS Rules
Change Justify-Content Value When Flex Items Overflow Container