The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".
The following errata were submitted by our customers and approved as valid errors by the author or editor.
Version |
Location |
Description |
Submitted By |
Date submitted |
Date corrected |
|
Page Page 2
2nd code example |
value = ((value & 0xffff0000) >> 16) + (value & 0x000ffff);
should be
value = ((value & 0xffff0000) >> 16) + (value & 0x0000ffff);
Note from the Author or Editor: Yup. It's not a functional problem, the code works fine, but 0x0000ffff is more clear.
|
Ryuichi Kubuki |
Jan 21, 2023 |
|
|
Page Page 19
3rd paragraph |
It says “What if calling that function removes something from the values vector you’re iterating over?” but the values in the code examples at Page 18 are const vector<int> & and values can't be removed in these const vectors. Is it meant to be a general statement or a comment on the code examples? The latter seems to be the case as it refers to the values vector specifically, then it is confusing.
Note from the Author or Editor: Yes, I agree there's some ambiguity here. I was actually referring to the example--it's C++ code, so the fact that you have a const reference to the vector doesn't preclude some other bit of code having a non-const reference to the vector. That's pretty much the prime argument for Rust.
I think it would make sense to insert this sentence immediately after the "What if calling that function..." sentence:
"You've got a const reference to *values*, so it may seem safe to assume it won't change, but the *reduceFunction* could easily have access to a non-const pointer to that vector and manipulate it in arbitrary ways."
|
Ryuichi Kubuki |
Jan 21, 2023 |
|
|
Page Page 20
The last code example |
Character::~Character() lacks
int index = 0;
for (; index < s_allCharacters.size(); ++index)
{
if (this == s_allCharacters[index])
break;
}
that is present in the code example in the github repo, it seems it is omitting too much to make it hard to read.
Note from the Author or Editor: Oops! Yes, I deleted a little too much code. The repo is correct. Well, it's correct, but that code is more complicated than it needs to be. The index is already known, we don't need to look it up, so this would be better:
Character::~Character()
{
s_allCharacters.erase(s_allCharacters.begin() + m_index);
for (int index = m_index; index < s_allCharacters.size(); ++index)
{
s_allCharacters[index]->m_index = index;
}
}
I'll update the repo to match this.
|
Ryuichi Kubuki |
Jan 21, 2023 |
|
|
Page Page 21
2nd paragragh |
"then checks that allCharacters returns them in the proper order"
should be
"then checks that getAllCharacters returns them in the proper order"
Note from the Author or Editor: Yes, it should be "getAllCharacters"
|
Ryuichi Kubuki |
Jan 21, 2023 |
|
|
Page Page 311
3rd paragraph |
"Another concept from C++ that has no Python analog is templates"
should be
"Another concept from C++ that has no JavaScript analog is templates"
given that it is in the JS section.
Note from the Author or Editor: Yes, an incomplete find + replace. Not sure how I missed that one!
|
Ryuichi Kubuki |
Jan 21, 2023 |
|
|
Page Page 32
Footnote 1 |
"Applesoft Basic" should be "Applesoft BASIC".
"My Basic variables" should be "My BASIC variables".
Note from the Author or Editor: Yup, it should be capitalized. Some dialects, notably Visual Basic, have decided to ignore the fact that BASIC is officially an acronym and capitalize it like a normal word, but "Applesoft BASIC" is correct.
|
Ryuichi Kubuki |
Jan 21, 2023 |
|
|
Page Page 34
1st paragraph |
In "You multiply each term by the domain value x taken to the Nth power", it mentions "term", and the preceding code example takes "terms" as a parameter, but isn't it a coefficient rather than a term? The 2nd code in Page 33 has realCoeffs[] and imagCoeffs[] as parameters that look like coefficients, not sure why they became "terms" in the next code.
Note from the Author or Editor: Sloppy language on my part; coefficient would be more accurate. So:
"You multiply each coefficient by the domain value *x* taken to the Nth power."
and:
void evaluateComplexPolynomial(
vector<complex<float>> & coeffs,
complex<float> x,
complex<float> * y)
{
complex<float> xN = { 1.0f, 0.0f };
*y = { 0.0f, 0.0f };
for (const complex<float> & coeff : coeffs)
{
*y += xN * coeff;
xN *= x;
}
}
|
Ryuichi Kubuki |
Jan 23, 2023 |
|
|
Page Page 36
2nd paragraph |
In this sentence
"Now you’re not just asking your programmers to adapt to and
use a foreign set of naming conventions—you’re asking them to write code with
those conventions as well"
it sounds like using a set of conventions and writing code with those conventions are 2 different things, but using conventions would include writing code. What does 'use a foreign set of naming conventions' actually mean?
Note from the Author or Editor: Good note. There's a spectrum of possibilities between being able to read something that uses a set of conventions and writing something from scratch using those conventions. Making a minor edit, say. I sort of meant to cover the part of this spectrum towards "read" by saying "use".
But! I think that this sentence would be better if we substitute "understand" for "use", leading to:
Now you’re not just asking your programmers to adapt to and understand a foreign set of naming conventions—you’re asking them to write code with those conventions as well.
|
Ryuichi Kubuki |
Jan 23, 2023 |
|
|
Page Page 38
2nd paragraph |
"single-stepping through LayoutWindows" and "in
the LayoutWindows function"
should be
"single-stepping through layoutWindows" and "in
the layoutWindows function"
Note from the Author or Editor: Yes. Vestige of the Sucker Punch naming conventions instead of the The Rules of Programming conventions.
|
Ryuichi Kubuki |
Jan 25, 2023 |
|
|
Page Page 53
2nd code example |
The constructor of SignQuery already has m_area, but the member variables doesn't have it. Instead of
vector<Color> m_colors;
Location m_location;
float m_distance;
regex m_textExpression;
aren't they like this?
vector<Color> m_colors;
Area m_area;
regex m_textExpression;
Note from the Author or Editor: Yes. I got tangled up in a cut + paste mess. The repo was wrong, too, just in a different way.
|
Ryuichi Kubuki |
Jan 29, 2023 |
|
|
Page Page 100
2nd paragraph |
"If you create an InvulnerableHandle"
should be
"If you create an InvulnerableToken"
Note from the Author or Editor: Yes, it should be InvulnerableToken. "Handle" is the Sucker Punch-ism for this concept, but I figured it was confusing in the context of the book.
|
Ryuichi Kubuki |
Feb 25, 2023 |
|
|
Page Page 103
3rd paragraph |
"Static analysis can’t pick up that sort of thing up."
It seems one of 'up' is redundant.
Note from the Author or Editor: Yes! The second "up" should be removed, leaving:
"Static analysis can't pick up that sort of thing."
|
Ryuichi Kubuki |
Feb 26, 2023 |
|
|
Page Page 112
Footnote 4 |
What does "(plus or minus)" exactly mean in this context? Is it about the parameter of malloc being a negative value cast into a large unsigned int?
Note from the Author or Editor: No, in this context "plus or minus" is just engineering-speak for "more or less" or "to a first approximation". Most of the time malloc is used for all dynamic allocation in C code, but it is possible to allocate things using other mechanisms--like calling the OS directly, or using the C run time's calloc function, or creating a big static buffer and suballocating out of it.
|
Ryuichi Kubuki |
Feb 28, 2023 |
|
|
Page Page 122
1st paragraph |
"three commented sections of getFactors"
should be
"three commented sections of factorValue"
given that it refers to the code with comments on Page 120.
Note from the Author or Editor: Yes, it should be "three commented sections of factorValue"
|
Ryuichi Kubuki |
Mar 05, 2023 |
|
|
Page Page 143
5th paragraph |
"which means more code in CPlayer::onSpotted"
should be
"which means more code in Player::onSpotted"
Note from the Author or Editor: Yes, it should be "Player::onSpotted". Another leak from the Sucker Punch side of my brain.
|
Ryuichi Kubuki |
Mar 08, 2023 |
|
|
Page Page 139
2nd paragraph |
"like only updating the eye icon in CPlayer::setStatus"
should be
"like only updating the eye icon in Player::setStatus"
Note from the Author or Editor: Yes, it should be "Player::setStatus"
|
Ryuichi Kubuki |
Mar 08, 2023 |
|
|
Page Page 191
1st code example |
lastIndex < searchLength;
should be
lastIndex - 1 < searchLength;
otherwise the last part of the search string is not checked.
Note from the Author or Editor: Good catch!
I confused myself with the name--in our internal naming convention "last" means the last valid index, and "mac" would be the index one past the last valid index. "lastIndex" is really more "macIndex" here.
Let's go with "lastIndex <= searchLength".
|
Ryuichi Kubuki |
May 23, 2023 |
|
|
Page Page 194
1st code example |
index < search.length();
should be
index - 1 < search.length();
otherwise the last part of the search string is not checked.
Note from the Author or Editor: Yes, good catch! Let's go with "index <= search.length()" instead.
|
Ryuichi Kubuki |
May 23, 2023 |
|
|
Page 200
1st paragraph |
"And you’d be surprised and"
should be
"And you’d be surprised at"
Note from the Author or Editor: Yes, "And you'd be surprised at" is what I intended.
|
Ryuichi Kubuki |
Apr 15, 2023 |
|
|
Page 205
Around the end of isServerBlocked |
log("expect string array for config.security.blocked_servers");
should be
log("expected string array for config.security.blocked_servers");
Note from the Author or Editor: You're right, log("expected string array for config.security.blocked_servers"); would be more consistent with the other error messages.
|
Ryuichi Kubuki |
Apr 17, 2023 |
|
|
Page 206
4th paragraph |
The Objects in "leading to a simple function that walks through nested Objects" are all in the code font, but the class name in the code is Object, so the last 's' in Objects should not be in the code font.
Note from the Author or Editor: Strictly speaking, I think you're right. I don't think I'd change this, though--I doubt readers will be confused, and switching fonts in the middle of the word would be unattractive.
|
Ryuichi Kubuki |
Apr 17, 2023 |
|
|
Page 212
2nd paragraph |
"our unpackConfig file can report an error and fail at startup time"
should be
"our unpackConfig function can report an error and fail at startup time"
Note from the Author or Editor: You're right, it should be "unpackConfig function", not "unpackConfig file", I mistyped. Good catch.
|
Ryuichi Kubuki |
Apr 19, 2023 |
|
|
Page 213
3rd paragraph |
"the “server.blockedServers” config file option is described as part of g_securityType."
should be
"the “security.blocked_servers” config file option is described as part of g_securityType."
Note from the Author or Editor: You're right, it should be "security.blocked_servers". I think I switched from "security.blockedServers" to "security.blocked_servers" and missed once instance of the old name.
|
Ryuichi Kubuki |
Apr 23, 2023 |
|
|
Page 217
2nd paragraph |
In this part, 'objects' seem to be 'classes', but are there any other things indicated by 'objects' here?
"mapping JSON key/value pairs into members of C++ structs or objects."
Note from the Author or Editor: Yes, using "objects" is sloppy here. "Classes" is a better choice.
|
Ryuichi Kubuki |
Apr 25, 2023 |
|
|
Page 229
1st paragraph |
From the description in the footnote 8, it seems 'lozenge' here refers to the stadium or discorectangle shape
mathworld.wolfram.com/Stadium.html
en.wikipedia.org/wiki/Stadium_(geometry)
while a lozenge usually refers to the diamond shape. Since the code also uses this word a lot, using 'lozenge' as a token of 'stadium' is OK but might still be confusing.
Note from the Author or Editor: Nice catch--I used the wrong word here. I meant "capsule". I have no idea what I was thinking. Probably that lozenges in the cough drop sense are rounded, not the diamond shape of the mathematical definition.
By the way, most of the definitions you'll find for "capsule" refer to 3D capsules, but you can define a capsule for any dimension >= 2.
|
Ryuichi Kubuki |
Apr 30, 2023 |
|
|
Page 235
2nd paragraph |
PostToStagingServer should be postToStagingServer.
ConnectToStagingServer should be connectToStagingServer. (2 occurrences)
PostBlob should be postBlob.
Note from the Author or Editor: Yup, I mis-capitalized all of these words... sigh. The the actual coding convention we use at Sucker Punch capitalizes the first letter of function names; looks like my brain was on autopilot.
|
Ryuichi Kubuki |
Apr 30, 2023 |
|
|
Page 235
6th paragraph |
ConnectToStagingServer should be connectToStagingServer .
Note from the Author or Editor: Yup, that's right, it should be "connectToStagingServer". Got my naming conventions mixed up.
|
Ryuichi Kubuki |
Apr 30, 2023 |
|
|
Page 276
3rd paragraph |
The last 's' in Units should not be in the code font given the struct name is Unit.
Note from the Author or Editor: Strictly speaking, you're right, but I don't think it's confusing, and using the same font is much more attractive.
|
Ryuichi Kubuki |
May 09, 2023 |
|
|
Page 276
1st paragraph |
"which squash doesn’t do"
should be
"which squashAdjacentDups doesn’t do"
Note from the Author or Editor: Yes, it should be "squashAdjacentDups". Changed the name at some point, missed an instance of the old name.
|
Ryuichi Kubuki |
May 25, 2023 |
|
|
Page 282
Last paragraph |
dev/null
should be
/dev/null
Note from the Author or Editor: Haha, sure! Might as well get the jokes right, too!
|
Ryuichi Kubuki |
May 31, 2023 |
|
|
Page 286
1st code example |
The spaces used for indentation of the lines like
nextValue = leftValues[leftIndex]
are 3 spaces unlike 4 spaces used at the beginning of these lines.
Note from the Author or Editor: Weird; that's super random. Not a big deal, the code will work as written, but switching to 4 spaces would be nice.
|
Ryuichi Kubuki |
May 28, 2023 |
|
|
Page 303
1st paragraph |
"the increasingly popular TypeScript extension of JavaScript lets you type annotations"
should be
"the increasingly popular TypeScript extension of JavaScript lets you add type annotations"
if it follows the last paragraph of the page 284.
Note from the Author or Editor: Yes, "lets you add type annotations" is what I meant. Good catch.
|
Ryuichi Kubuki |
May 30, 2023 |
|
|
Page 313
3rd paragraph |
'globalNumbers' only exists in the Python version in the other Appendix. Also 'numbers' in this paragraph is confusing with the 'numbers' in "let numbers = [3, 5, 8, 13];"
Note from the Author or Editor: I agree. I think the Python version of this is more clear--having two "numbers" variables is confusing. Let's change the Javascript example to:
function makeChanges(number, numbers) {
number = 3;
numbers.push(21);
console.log(number, numbers);
}
let globalNumber = 0;
let globalNumbers = [3, 5, 8, 13];
console.log(globalNumber, globalNumbers);
example5.makeChanges(globalNumber, globalNumbers);
console.log(globalNumber, globalNumbers);
I got the output slightly wrong, too--I cut + pasted the Python output. Oops! The actual Javascript output is:
0 [ 3, 5, 8, 13 ]
3 [ 3, 5, 8, 13, 21 ]
0 [ 3, 5, 8, 13, 21 ]
|
Ryuichi Kubuki |
May 30, 2023 |
|