I'm following along with Robert Nystrom's Crafting Interpreters to learn how to write an interpreter (which still seems magical to me), as well as to learn (more) Ruby and RBS.
Below are a couple of examples to where the Ruby code is just so much more elegant and beautiful than Java.
These put a smile on my face when I wrote them. 😍
while (peek() != '\n' && !isAtEnd()) advance();advance until peek == "\n" || eof?The Ruby code reads just almost like plain English. Swapping while with until to flip the condition makes it
crystal clear.
private void resolveLocal(Expr expr, Token name) {
for (int i = scopes.size() - 1; i >= 0; i--) {
if (scopes.get(i).containsKey(name.lexeme)) {
interpreter.resolve(expr, scopes.size() - 1 - i);
return;
}
}
}def resolve_local(expr, name)
@scopes.reverse_each.with_index do |scope, i|
if scope.key? name.lexeme
@interpreter.resolve(expr, i)
return
end
end
endUsing reverse_each makes the intent immediately clear. There's also no need for scopes.get(i).
Replacing scopes.size() - 1 - i with just i avoids any chance for off-by-one errors.
@Override
public Void visitCallExpr(Expr.Call expr) {
resolve(expr.callee);
for (Expr argument : expr.arguments) {
resolve(argument);
}
return null;
}def visit_call(expr)
resolve expr.callee
expr.arguments.each { resolve it }
endI rest my case.