Comment by kace91

Comment by kace91 20 hours ago

19 replies

I don’t have an issue with the “everything’s an object” part, because it _is_ consistent, even though it gets a bit trippy when classes are objects as well and they are implementation of a Class class which is an implementation of itself (trickery again!).

The issue is more with this part:

>The `times` method exists on the Integer classes because doing something exactly an integer number of times happens a lot in practice.

It is practical, but it breaks the conceptual model in that it is a hard sell that “times” is a property over the “5” object.

The result is cleaner syntax, I know, but there is something in these choices that still feels continually “hacky/irky” to me.

WJW 20 hours ago

Perhaps I've been doing Ruby for too long, but it's still not that weird to me. The quantity "5" is very abstract without anything to have "5" of. That is why "5.days" and "5.times" exist, among others. Mathematically it makes just as much sense to start with the amount and add the unit later than it does to start with the unit and add the amount later (ie like `time_to_wait = SECONDS_IN_A_DAY * 5` as you might do in some other languages).

  • kace91 19 hours ago

    Maybe it is clearer if I explain it in syntactic terms? In my mental model objects are nouns (described entities) and methods are verbs - actions over the noun.

    process.start() is the action of starting done by the the noun that is the process.

    It's not exactly a matter of naming, as some methods are not explicitly verbs, but there is almost always an implicit action there: word.to_string() clearly has the convert/transform implication, even if ommitted for brevity.

    I see no path where 5 is a noun and times the verb, nor any verb I can put there that makes it make sense. If you try to stick a verb (iterate?) it becomes clear that 5 is not the noun, the thing performing the iteration, but a complement - X iterates (5 times). Perhaps the block itself having a times object with 5 as an input would make it more standard to me (?).

    But I do understand that if something is extremely practical a purist/conceptual argument doesn't go very far.

    • bigtunacan 16 hours ago

      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.

      • anamexis 10 hours ago

        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.

    • oezi 19 hours ago

      I have been doing Ruby for so long that it feels very natural to apply a method in this way on the instance.

      false.not

      applies the not method on the false instance in the same way that

      car.start

      in every OO language calls the start method on car as the receiver.

      So filter(list) feels just wrong when you are clearly filtering the list itself.

      • nasmorn 19 hours ago

        Although I prefer Elixir currently I agree that ruby at least goes all the way in on OO and not having to remember which feature is implemented as a language syntax and what is just a method invocation is a strength not a weakness. It is different in other languages for historical performance reasons really.

      • kace91 18 hours ago

        list.filter is ok! Filtering is an action that applies to a list

        false.not is borderline but if read as false.negate it makes sense (negating is an action that applies to a Boolean value). That wording screws the chaining though.

        5.times is where the pattern breaks: times is not an action that applies to a number (nor an action at all). It’s the block the one that should repeat/iterate - but Ruby breaks the rule there and blocks are not an object (!). If they were you could block.repeat(5) which IMO is cleaner.

gray_-_wolf 20 hours ago

> that “times” is a property over the “5” object

Maybe here is the confusion, ruby is based on message passing, so the `times` is a message you are sending to 5, not a property of it.

  • bigtunacan 17 hours ago

    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

majormajor 13 hours ago

When you're new it just looks like a weird-but-reasonable syntax.

When you learn the language you really fall into two camps:

- ah, yes, this is unusual, but it's consistent and now i understand the language

- this is way too clever

I'm more in the first camp.

cortesoft 10 hours ago

Times isn’t a property of the 5 object, it is a method of the 5 object.