We’re kind of seeing that with those private jet trackers. But that’s not changing anything except getting those accounts banned from social media.
We’re kind of seeing that with those private jet trackers. But that’s not changing anything except getting those accounts banned from social media.
This should be illegal. There is absolutely no good reason this should be available to anybody. It should also be considered unconstitutional; if one of those dots is a person, whether you directly know who the person is or not, it should violate the right to privacy and the right of illegal search and seizure — no questions asked.
Because right now’s political climate is about how abortion is being billed en masse as murder, and people are having to go to other states to get abortions (even for miscarriages), so the states that bill abortion as murder want to be able to prosecute the women. So there are a lot of fears that states will be tracking women through tools like this, and it turns out the fearful were correct.
Let’s bring back those animated gifs (mailbox and under construction) from the 90s. That’ll get everyone riled back up again.
I wouldn’t. Not from this example anyway. YAGNI is an important paradigm and introducing plenty of classes upfront to implement trivial checks is overengineering…
Classes, functions, methods… pick your poison. The point is to encapsulate your logic in a way that is easy to understand. Lumping all of the validation logic into one monolithic block of code (be it a single class, function, or methods) is not self-documenting. Whereas separating the concerns makes it easier to read and keep your focus without mixing purposes. I’m very-engineering (imo) would be something akin to creating micro services to send data in and get a response back.
Edit: Your naming convention isn’t the best either. I’d expect
UserInputValidator
to validate user input, maybe sanitize it for a database query, but not necessarily an existence check as in the example.
If you go back to my example, you’ll notice there is a UserUniqueValidator
, which is meant to check for existence of a user.
And if you expect a validator to do sanitation, then your expectations are wrong. A validator validates, and a sanitizer sanitizes. Not both.
For the uninitiated, this is called Separation of Concerns. The idea is to do one thing and do it well, and then compose these things together to make your program — like an orchestra.
👆 This. In my experience, I’ve seen a lot of developers get upset about “their code” not being used, time wasted, or someone else changing the code after the fact. Who cares? Once you commit that code, it’s no longer your code. It’s the company’s code. Your paycheck will reflect the same amount of money regardless — and if it doesn’t, you may want to find a better employer. 😅
async function createUser(user) {
validateUserInput(user) || throwError(err.userValidationFailed);
isPasswordValid(user.password) || throwError(err.invalidPassword);
!(await userService.getUserByEmail(user.email)) || throwError(err.userExists);
user.password = await hashPassword(user.password);
return userService.create(user);
}
Or
async function createUser(user) {
return await (new UserService(user))
.validate()
.create();
}
// elsewhere…
const UserService = class {
#user;
constructor(user) {
this.user = user;
}
async validate() {
InputValidator.valid(this.user);
PasswordValidator.valid(this.user.password);
!(await UserUniqueValidator.valid(this.user.email);
return this;
}
async create() {
this.user.password = await hashPassword(this.user.password);
return userService.create(this.user);
}
}
I would argue that the validate routines be their own classes; ie UserInputValidator
, UserPasswordValidator
, etc. They should conform to a common interface with a valid()
method that throws when invalid. (I’m on mobile and typed enough already).
“Self-documenting” does not mean “write less code”. In fact, it means the opposite; it means be more verbose. The trick is to find that happy balance where you write just enough code to make it clear what’s going on (that does not mean you write long identifier names (e.g., getUserByEmail(email)
vs. getUser(email)
or better fetchUser(email)
).
Be consistent:
get*
and set*
should be reserved for working on an instance of an objectis*
or has*
for Boolean returnsfetchUser()
, validate()
, create()
UserService.createUser()
valid
vs isValid
const
unless you absolutely have to reassign its direct value; I.e., objects and arrays should be const
unless you use the assignment operator after initializationif {}
statements. Short-circuiting is cutesy and all, but it makes code more complex to read.{}
to create small groups of related code. You’re not penalized for the white space because it gets compiled away anyway.There is so much more, but this should be a good primer.
That’s an excellent question. Unfortunately I do not have an answer. But I believe it’s worth discussing some means of redundancy for the IA; even if it’s as simple as rsync to other hosts.
Maybe it’s time to federate the IA.
Ssh! 🫢 You’ll ruin the joke!
Linus Torvalds: creator of Linux and Git, and hero to all English teachers everywhere!
People need to chill with the language fanaticism. It’s one thing to make jokes and rip on a language for its quirks, but at the end of the day it’s just a language. If you truly don’t like it, don’t use it. I’m going to take a stab and guess that there is enough Linux kernel source to go around to both the c devs and rust devs. Just be glad they’re not trying to rewrite it in JavaScript. 😉
Not entirely true.
I don’t understand why they don’t just migrate .io into a non-country code domain. Hell, they could auction it off to anybody (company, country, or person) who wants it bad enough. Let it live alongside the other custom domains.