The latest from Beardo:
This post brought to you by static typing
Sun, Feb 14, 2021
ruby go programing-languages
I first learned Ruby and Ruby on Rails back in 2011. At the time I was coming from the Java world and it was a breath of fresh air. Ruby and Rails has much less verbosity than Java and you could get a lot done in a short amount of time. I happily did Rails for six years and didn’t see too many problems with it. For various reasons, the next project I worked on was done in Go. I worked on that project for a few years, and am now back on the Rails, except all of the rough edges in Ruby/Rails are much more obvious.
Ruby is an extremely dynamic language. You can basically redefine everything during runtime. There are benefits to such flexibility, but it’s not without pitfalls. The biggest thing that I find lacking in Ruby/Rails is static types. Static typing might feel like handcuffs when you’re used to being able to define and redefine anything at anytime, but it has some serious benefits. The biggest benefit in having static types is that the compiler can point out things that are wrong before you even get a chance to run your code. Let’s look at some Ruby code:
def divide(x, y)
return "Can't divide by 0" if y == 0
x / y
end
You wouldn’t write this to use in the real world, but Ruby won’t stop you. Is it better this way though? Is it just “caveat emptor” for developers? Let’s look at a real world situation I ran into. A Ruby library I used documented a feature that you could implement a method that would be called when a query wasn’t authorized and it would return the response of that method instead of raising an exception. It looked like this:
class MyQuery < BaseQuery
def unauthorized(owner, value)
{
status: "Error",
message: "#{owner} is now allowed to access that."
}
end
end
It’s a neat feature except for one thing: it completely bypassed permission checks. Of course, the permission checks were what we were using to enforce permissions. We actually had some tests that would still pass because the correct result was being returned, the problem was that the underlying GraphQL mutation was still being executed. Digging into the library code (and about 75 levels deep stacktrace) I found a function that was doing this:
def authorized?
authorized = check_authorization
result = if !authorized && self.method_defined?(:unauthorized)
self.unauthorized
else
authorized
end
end
Where this goes wrong is that typically methods ending in ?
return true
or false
. Nothing in Ruby enforces this, it’s just a convention. Further, Ruby will coerce other types when used in conditional so that our hash in the unauthorized
override above when interpreted in a condtional will be evaluated to true
. If Ruby had a stronger type system, the return value of the authorized?
function in the library would be a bool
and a compiler would have reported the type mismatch.
In order to get the same checking that a compiler would give you in a statically typed language, Rubists have taken to writing large amounts of unit tests. You can get a long way with such tests, and having a statically typed language doesn’t preclude the need for testing, but you can eliminate some classes of errors without any work by the developer by using a statically typed langage.
Thanks for reading.
— Beardo
Hello, nobody
Sun, Feb 7, 2021
It’s really happening. The first post on my new blog. Now I’ll be able to share my thoughts with millions of people.
Or maybe not. Hi mom.
Aren’t blogs so 2003?
Probably, but I’m not sure there’s a better online medium for long form written content. I’m using this as a way to share some of my thoughts on various topics and practice written communication. Most of the topics will be technology and software development related because those are things I’m most familiar with.
I’ve chosen to self host the site instead of using a blogging platform because I’m a developer, and every problem always has a solution that involves writing some amount of code if you’re a developer. I’m not crazy enough to write my own blogging platform though, I use hugo to process the markdown of the posts and generate static HTML. The site also uses tailwind for the styling. The design is done by me, but don’t judge too harshly because I’m not a designer. Everything is stored in a github repository, built with Cloudbuild on GCP and hosted via Firebase. All of these technologies were chosen because I wasn’t familiar with them, so this gave me an opportunity to try them.
I’m not comitting to any specific frequency for posting. I’ll just write things as I come up with them.
Thanks for reading.
— Beardo