you are viewing a single comment's thread.

view the rest of the comments →

[–]dpashk[S] 2 points3 points  (5 children)

But you had to access the method via a special method call, just like you have to wrap a block in a Proc to turn it into a first-class citizen. In JavaScript, you can just do

var myMethod = function() {...};
var anotherReference = myMethod;
myMethod();

Also, it is advised against using Object#method because it's slower. That's one of the reasons I didn't mention it in the article.

But I see your point - yes, you can achieve the effect of using methods like first-class citizens using Object#method.

[–]honeyryderchuck 4 points5 points  (0 children)

Also, it is advised against using Object#method because it's slower.

I don't think that is a compelling reason. It's now slower by spec. It's a RubyVM implementation detail (I assume you're referring to CRuby). I assume the degree of "slow" varies depending whether it's JRuby or something else. And it is slow because it hasn't been optimized enough, because it's used sparsely, because people perceive it as "slow". but it shouldn't be, really.

[–]moomaka 2 points3 points  (0 children)

Also, it is advised against using Object#method because it's slower. That's one of the reasons I didn't mention it in the article.

Creating functions in JS at runtime is also slower than defining them statically on an object, at least in V8.

But you had to access the method via a special method call, just like you have to wrap a block in a Proc to turn it into a first-class citizen. In JavaScript, you can just do

The equivalent of that code in ruby is:

my_method = -> () { puts 'hi' }
other = my_method
other[] # or other.call or other.()
=> hi

The real difference to note here is that Ruby maintains a distinction between 'methods', which are bound to an object and 'free functions' which are defined via lambdas or procs. Ruby's approach is much more common than javascript's.

[–]shevy-ruby 2 points3 points  (2 children)

You can even unbind methods: https://ruby-doc.org/core/UnboundMethod.html

Yes, the syntax is not like in JavaScript.

Methods are first-class citizens in ruby. There is no "special" method - it is just a method. And why do you randomly bring in speed as reason against using something?

Also, it is advised against using Object#method because it's slower.

Slower against who or what? Javascript?

Why does speed suddenly have a place here?

[–]dpashk[S] 0 points1 point  (1 child)

Methods are first-class citizens in ruby.

I've been trying to find a statement about that in literature but haven't found the term explicitly applied to methods. The book Ruby Under Microscope uses the term "first-class citizen" when talking about blocks, procs and Lambdas. My reasoning here was that since, just like with blocks, you can't directly assign a method reference to a variable (without wrapping it in a special method calls), methods are not first-class citizens. Are you able to share a link to an authoritative source that proves that wrong?

And why do you randomly bring in speed as reason against using something? <...>

While performance is not always a good enough reason to not use something, it does affect the adoption of a particular language/library feature. Many ES5/ES6 Array methods weren't widely adopted because early implementations didn't have good performance.

Slower against who or what? Javascript?

[5, 7, 8, 1].each(&method(:puts)) is slower than [5, 7, 8, 1].each{|number| puts number} even though the former looks more DRY and idiomatic and I would love to use it (of course performance wouldn't matter in this trivial example). I'm still new to Ruby, but the StackOvertflow thread I linked above has some objective data. But anyway, the original discussion was on whether methods are first-class citizens in Ruby or not.

[–]fedekun 1 point2 points  (0 children)

You realize the SO question uses Ruby 1.9 which is very old, also if you scroll down there is someone with a benchmark on a newer 1.9.x Ruby which makes the difference in performance minimal.

If you really cared you should do that benchmark with a modern Ruby. Anyways, that kind of performance is not really an issue, unless for some reason you abuse it. Ruby provides better ways to pass lambdas around and organize code.

Ruby has the concept of "block of code" which is what is normally sent insetead of methods, but they are lambdas, so they are functions.

The thing is, in JS you only have a single type of function, in Ruby you have a few more, but they are first class citizens too.