02 — Methods and arguments¶
One line: A Ruby method call needs no parentheses, no return, no self, and its argument list can carry positionals, defaults, splats, keywords and a block — and each of those is a place where a Python reader's model needs one adjustment.
This chapter is about the shape of a call and of a definition. Ruby drops the parentheses, returns whatever the last expression produced, evaluates a default argument fresh on every call, marks dangerous methods with ! and predicates with ?, makes + and [] and ! ordinary methods you can define, sends a receiverless call to an implicit self, skips a call on nil with &., and makes an assignment obj.x = v evaluate to v no matter what the setter's body returns.
A Python programmer arrives with most of the right ideas: functions take positional and keyword arguments, *args and **kwargs collect the rest, and operators are dunder methods underneath. What breaks is the details — Python needs parentheses to call, returns None unless you say return, evaluates a default once at def time (the mutable-default trap), has no ? or ! in a name, and treats assignment as a statement with no value. Every page here prints both behaviours side by side.
| Lesson | Level | The one thing |
|---|---|---|
| Parentheses are optional, but the space is not | 101 | a bare name is a call, and puts (1+2)*3 is not puts(1+2)*3 |
| The last expression is the return value | 101 | no return needed; a method that ends in puts returns nil |
| Arguments: positional, keyword, splat and block | 201 | the eight kinds of parameter, ... forwarding and the three ArgumentError messages |
| Default arguments are evaluated on every call | 201 | def f(a = []) is fresh each call; Python's def f(a=[]) is not |
| Bang means dangerous, question mark means predicate | 101 | sort! mutates, strip! returns nil when nothing changed, empty? answers |
| Operators are methods, except the ones that are not | 201 | +, [], <=>, ! are methods you define; &&, ||, = are syntax |
self is the implicit receiver |
201 | a receiverless call goes to self; a setter needs self.x = |
&. skips the call when the receiver is nil |
101 | nil&.length is nil and the arguments are not even evaluated |
| A setter returns its argument, not its body | 201 | obj.x = 5 evaluates to 5 whatever def x= returns |
Read more¶
- Ruby docs: Methods ↗ — parameter kinds,
return, and thedefforms - Ruby docs: Calling methods ↗ — receivers, arguments, splats, keywords, blocks and
&. - Python tutorial: Defining functions ↗ — defaults, keyword arguments,
/and*markers - Python reference: Calls ↗ — how a Python call binds its arguments