3 ms·
Ruby syntax & behaviour is in a hazy middle ground between message passing and method calling. Writing Ruby in a message-passing style feels natural and easy,
by inopinatus 8y ago
Ruby syntax & behaviour is in a hazy middle ground between message passing and method calling. Writing Ruby in a message-passing style feels natural and easy, which is why many Rubyists will recommend it, and doing so enables looser coupling between objects.
To me, it's the difference between pulling the strings on a puppet (method calling) vs placing a request to a colleague (messaging).
However I don't think anything in the Ruby docs ever claims that it has a message-passing intent. I think the option to write in this style is really a byproduct of duck typing combined with a Ruby object's ability to arbitrarily and dynamically reconfigure its own dispatch table. If Matz really intended a message-passing style, then Object#send would've been split into Kernel#send and Object#receive, and there'd probably be a Message class rather than just using symbols.
Given the new shorthand of object.:name in 2.7 for object.method(:name) one could even argue that Matz is drifting Ruby back towards an early binding style. However I don't see myself using that syntax much outside of block parameters to Enumerable methods and the like.
Overall I think the stylistic options are a strength and we don't particularly need to resolve the dichotomy to write good Ruby.
- chrisseaton 8y ago> However I don't think anything in the Ruby docs ever claims that it has a message-passing intent. There is of course the `Kernel#send` method, which implies the model is messages being sent. It's not called `call`.
- inopinatus 8y agoI think you mean Object#send? I actually think that's misnamed, I think it should be named Object#receive because that's what happens - you're forcing an object to receive a symbol for (by default) dispatch through its method table. The fact it isn't invoked for regular method invocation is kinda indicative of Ruby _not_ being a pure message passing language, even if we like treating it that way.
- chrisseaton 8y ago> I think you mean Object#send? It's definitely Kernel#send. Object defines no instance methods at all. > Kernel.instance_methods(false).include?(:send) => true > Object.instance_methods(false).include?(:send) => false > Object.instance_methods(false) => [] https://github.com/ruby/ruby/blob/v2_6_2/vm_eval.c#L2163 https://github.com/ruby/ruby/blob/v2_6_2/vm_eval.c#L2163
- inopinatus 8y agoFascinating, the docs are misleading on this point. http://ruby-doc.org/core-2.6.2/Object.html#method-i-send http://ruby-doc.org/core-2.6.2/Object.html#method-i-send because Object includes Kernel and it's just easier to find, I guess. That's a somewhat arcane implementation detail though. What about the meat of the discussion?
- chrisseaton 8y agoI don't think Ruby is message passing either because the caller determines which method to call, based on the object's method table. #method_missing is just another method to be called by the caller - it isn't an example of the object being able to determine what happens. I think #send is really #call, but I think the name implies someone somewhere thought it was message passing. If I'm being uncharitable I think applying the term 'message passing' to Ruby is a bit of making something sound more sophisticated and elaborate than it is. They're method calls - it's pretty simple already and doesn't need a complex concept on top of that.
- inopinatus 8y agoIt merely remains to fork and/or invent a language that otherwise looks almost exactly like Ruby but with message passing only.
- macintux 8y agoElixir?
- 0x445442 8y ago> To me, it's the difference between pulling the strings on a puppet (method calling) vs placing a request to a colleague (messaging). This is the way I think about it as well, the more concise notion is ask don't tell. By don't tell I'm thinking of telling an object to change it's state directly. This distinction can be very, very subtle.