Ok, got this solved, thanks to tex core - Detecting catcode in parameter text - TeX - LaTeX; especially this note from @HendrikVogt:
This has nothing to do with catcodes of \fooA or \fooB. The \ifx test just sees that the parameter texts of the two macros are different (they contain different @s), so it turns out negative. The \ifx test doesn't care what the difference is.
... which means that, however, it does have to do with the catcodes of the characters of a "string content" of a "variable" (command)... and the \detokenize
snippet by @Jason finally put this all in place.
One other problem I've frequently encountered, is that sometimes when I do, say \detokenize{\command}
in an \edef
and then try to \typeout
the output - instead of the characters of the content, I see \command
again (understood apparently as a single token). @Jason's use of \expandafter made me finally realize that such constructs should be written:
\edef\tpmx{\expandafter\detokenize\expandafter{\mycommand}}
... the first \expandafter
"escaping" the \detokenize
- and the second one escaping the {
curly brace - so that \mycommand
can be expanded down to its content first; and \detokenize
can subsequently work on the characters of the content (the variable value). (note however that there is no need for such escaping when \detokenize
works on #1
- the stanza \edef\tmphwb{\detokenize{#1}}
seems to work just fine)
So, in brief - it is about the catcodes (I guess); and once we have to compare strings that we expect should have the same (ASCII) content, but somehow ended up with differing catcodes (from say diverse macros) - then we can call \detokenize
to "reset" the catcodes of characters of both strings before comparison - and then the \ifx
comparison can be seen to work:
=IOIOXX=12=IOIOXX=12=
!not equal
!not equal
!not equal
=IOIOXX=hello=IOIOXX=hello=
!not equal
!not equal
!not equal
=IOIOXX=IOIOXX=IOIOXX=IOIOXX=
!not equal
!not equal
\~equal
The above pdflatex
terminal output was produced with this modification of the OP MWE code:
\documentclass{article}
\def\testStr#1{IOIO#1}
\newcommand{\doTest}[1]{%
\edef\tmphwp{\testStr{XX}} %
\edef\tmphwb{\detokenize{#1}} %
% \edef\tmphwc{\detokenize{\tmphwp}} % NO: outputs \tmphwp!
% to have \detokenize{\tmphwp} show
% actual content as expected here,
% MUST use two \expandafter's:
% one to skip \detokenize, and other to skip the
% brace; - so \tmphwp can be expanded first!
\edef\tmphwc{\expandafter\detokenize\expandafter{\tmphwp}} %
\typeout{=\tmphwp=#1=\tmphwc=\tmphwb=} %
%
\ifx\tmphwp#1{%
\typeout{\~equal}%
}\else{%
\typeout{!not equal}%
}\fi %
%
\ifx\tmphwp\tmphwb{%
\typeout{\~equal}%
}\else{%
\typeout{!not equal}%
}\fi %
%
\ifx\tmphwc\tmphwb{%
\typeout{\~equal}%
}\else{%
\typeout{!not equal}%
}\fi %
\typeout{ ^^J } % newline in terminal stdout
}
\begin{document}
\doTest{12}
\doTest{hello}
\doTest{IOIOXX}
\end{document}
Well, hope this helps someone,
Cheers!
\ifx\tmphwp IOIOXX
which is of course false, because\tmphwp
is a control sequence andI
is a character.