It’s not just about practicality. Ruby is using message passing, not method calling. This is fundamentally different and a bit foreign to the larger community. Then ruby layers syntactic sugar on top that hides this.
Behind the scenes everything is a message passed using __send__ and you can do this directly as well, but you generally don’t.
So when you write
5.times { puts "Hello" }
It’s sort of expected by the average programmer that you are telling 5 to call the times method and expect it to exist and do what it’s told.
In reality you have indirectly sent a message that looks like
5.__send__(:times) { puts "Hello" }
What we are really doing is sending a message to 5 (the receiver) and giving it the opportunity to decide how to respond. This is where method_missing comes in to allow responding in a custom fashion regardless if a method was explicitly defined.
So you’re not telling 5 to call the method times, rather you are asking, “Hey 5, do you know how to handle the message times?”
These are fundamentally different things. This is actually super important and honestly hard to really grok _especially_ in ruby because of the syntactic sugar. I came from a C/C++ background originally, then Java and then moved to Ruby. After a few years I thought I understood this difference, but honestly it wasn’t until I spent a couple years using Objective-C where message passing is happening much more explicitly that I was able to truly understand the difference in a way that it became intuitive.
I’m a rubyist, but how is message passing fundamentally different from method calling? I get that method_missing adds a twist, but your comment doesn’t explain what the fundamental difference is.
Especially in the context of Fixnum#times. How does message passing vs method calling matter there? #times is just a method on Fixnum.
Because it leaves it up to the object being called what to actually do with the message. The object you're talking to might be forwarding its messages to another object in another ruby instance on another machine (if the current machine is getting fully loaded, etc), and the caller would be none the wiser. And crucially, the caller wouldn't have to be modified to enable this. The logic for this would be entirely within the object being called.
So the difference isn't just with method_missing.
With "method calling" as you put it, the program blows up if that object doesn't have that method, WHEN YOU CALL IT.
Basically, this smalltalk oo paradigm is about shifting where you put more of your logic. At & around the "call" site, or within the object whom you're calling & entrusting to do something useful with it.
All hearkening back to Alan Kay's original ideas about biology influencing how we organise code, and having a program be 1000's of "little black boxes" where work gets done by all these boxes talking to each other.
Which is why smalltalk (& ruby implements the Smalltalk object model to its entirety) actually has an awful lot in common with Erlang & other BEAM runtimes, even though those are functional languages. Because once you get beyond the techy buzzwords, the main ethos behind them is actually quite similar.
I guess what I’m getting at, is that I don’t understand how the difference actually informs anything concretely, as in the example of Fixnum#times, where this discussion started. Why is it super important to understand this fundamental difference?
Fixnum#times isn’t a great example, I only used it since the parent used it to illustrate their confusion and quite frankly a concrete useful example is to complex for this format.
ActiveRecord has changed a lot over the years, but as an example in the original ActiveRecord you used dynamic finders. None of the finder methods existed initially, but if you passed a message to an active record object for a non existent method rather than fail it would determine if that should be a method and then it would build and persist a method to the process for future calls.
It allows for some really interesting and powerful applications in horizontally scaling as well.
> I’m a rubyist, but how is message passing fundamentally different from method calling?
The difference is fairly subtle most of the time in practice, which is why dynamic OO languages like Ruby that use message passing can mostly look like OO languages that use method calling, though it is significant behind the scenes and opens up a lot of possibilities; one of the more obvious practical differences is that it is why Ruby can capture and handle unknown "method calls" via "method_missing", which works the way it does because the version of __send__ defined in BasicObject looks for an existing method matching its first argument in the object's inheritance chain, and if it finds that calls it, and if it doesn't find one does the same thing with the "method_missing" method.
There's a lot that can be built on top of this, either leveraging method_missing or more directly.
Though I think the more relevant issue upthread isn't message passing vs method calling but narrow vs broad conception of nouns/agents.
I think you’re right, but I also suspect that doesn’t clear up anything for most people as in my experience they generally don’t grok the difference unless they’ve already spent a significant amount of time in something like smalltalk or Objective-C
No, they would know exactly what they know now. Employers already report your earnings to both the federal and state IRS agencies and pay your withholdings automatically adjusted for your dependencies. So a simple form that says you made X and claimed Y dependencies. Click submit to confirm…
That would be simple enough for most people (1 job, 1 home, maybe some kids) and it doesn’t require the government to know anything additional.
In that most common scenario no tax accounting service should be needed. Honestly a 1040 isn’t that complicated in that scenario either, but is still too difficult for a good number of people and it’s just unnecessary.
In April 2016, Rovi acquired TiVo for $1.1 billion.[8]
In December 2019, it was announced that TiVo would merge with Xperi Corporation. The merger completed in May 2020.[9]
Xperi itself also split apart in 2022, so it's effectively 3 companies removed from its original roots. Basically at this point it is only valuable for the vague nostalgia consumers have for the brand.
Sam Altman made a post on Reddit in 2023 implying OpenAI had achieved AGI internally. Later he “clarified” it was a joke, however there was some speculation that he didn’t understand what AGI actually meant at the time.
In both cases it depends on the area of the state and how populous. Far southern Iowa near Whatcheer for example is mostly gravel with paved roads only in the cities and major highways, but by contrast nearly the entire corridor area is well paved. Same for most of the Boone area.
Wisconsin is no different in that. Most of Jackson, Levis, BRF, and that whole area is gravel except for major highways and in town. Pretty poorly maintained gravel at that.
The roads do seem disorganized and wandering, but much of that is because the roads are built wherever they won’t flood since we’re nothing but marshes, wetland, lakes, rivers and ponds
I acknowledge this may not be a 'bad' attribute, it could be Iowa just has so many unpaved extra roads it skews it. But when I think Iowa, I think driving on rough roads.
We have 100s of queues processing millions of jobs in sidekiq queues at any given time.
These are data and compute heavy workloads that take anywhere from minutes to hours for a request to be completed, but the UI takes this into account.
Users submit a request and then continue onto whatever is the next thing they intend to do and then they can subscribe to various async notification channels.
It’s not the right choice for everything, but it’s the right choice for something’s.
Behind the scenes everything is a message passed using __send__ and you can do this directly as well, but you generally don’t.
So when you write
5.times { puts "Hello" }
It’s sort of expected by the average programmer that you are telling 5 to call the times method and expect it to exist and do what it’s told.
In reality you have indirectly sent a message that looks like
5.__send__(:times) { puts "Hello" }
What we are really doing is sending a message to 5 (the receiver) and giving it the opportunity to decide how to respond. This is where method_missing comes in to allow responding in a custom fashion regardless if a method was explicitly defined.
So you’re not telling 5 to call the method times, rather you are asking, “Hey 5, do you know how to handle the message times?”
These are fundamentally different things. This is actually super important and honestly hard to really grok _especially_ in ruby because of the syntactic sugar. I came from a C/C++ background originally, then Java and then moved to Ruby. After a few years I thought I understood this difference, but honestly it wasn’t until I spent a couple years using Objective-C where message passing is happening much more explicitly that I was able to truly understand the difference in a way that it became intuitive.