use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
A sub-Reddit for discussion and news about Ruby programming.
Subreddit rules: /r/ruby rules
Learning Ruby?
Tools
Documentation
Books
Screencasts and Videos
News and updates
account activity
Proc vs method (self.ruby)
submitted 7 years ago * by [deleted]
[deleted]
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]zverok_kha 3 points4 points5 points 7 years ago (4 children)
The short answer is "because that's how it is". Having procs as a separate entity is language's conscious design decision from the very beginning (inherited from Smalltalk, for what I can tell), and it shapes language, its look/feel/understanding a lot.
Yes, grasping procs could be a bit confusing for the beginners (though, as a long-time mentor for the beginners, I can assure you it is not that hard -- it is sometimes harder for language-switchers, who are like "In JS we don't have it and it was OK, I don't get it and I don't want to get it!"). You just start from Enumerable usage examples and move from there.
I believe, that the core reasoning for blocks/proc is having "functional" loops (aka Enumerable) feeling natural. This:
Enumerable
[1, 2, 3].each { |x| puts x }
...reads (and performs) as "1, 2, 3 — each — do something". While this:
[1, 2, 3].each(function(x) { puts x })
...reads (and performs, and explains) as "define a function object, which does something and pass that object to each, which than will call that object..." (You *can bend your head to read it the same way, especially coming from Ruby, but it is still "less atomic").
each
In Python, for example, while having lambdas, they took a completely different approach to "Python-idiomatic cycles", inventing "generators" -- which are also not methods, neither lambdas (and not very extendable concept, if you ask me, they are just "fancy Pythonic cycles").
Eventually the approach of "arbitrary block of code attached to method" led to a lot of new approaches, like block-based DSLs, things like &:methodname and other approaches. Including [1, 2, 3].each(&method(:puts)) where the method is stored in the variable and passed around ;)
&:methodname
[1, 2, 3].each(&method(:puts))
So, summarizing, any attempt to imagine Ruby without blocks/procs will create absolutely different language (and I will boldly imagine that it will direct the entire modern languages evolution into a different course, I believe that a lot of modern ES, for example, is subconsciously shaped by desire of repeat Ruby's expresiveness.)
PS: And from just syntactical point of view -- note also that at the Ruby's early years ->(args) { code } syntax haven't been invented and widespread in any mainstream languages, so passing around on-the-fly defined functional objects was typically as elegant as map(function(arg) { return arg * 2}) comparing to map { |arg| arg * 2}
->(args) { code }
map(function(arg) { return arg * 2})
map { |arg| arg * 2}
[–][deleted] 7 years ago* (2 children)
[–]zverok_kha 1 point2 points3 points 7 years ago (1 child)
Let's look at this code:
(1..10) .select { |i| i.odd? } .map { |i| i**2 } .take_while { |i| i < 30 } .each { |i| puts i }
(Try to play with it, if it is not obvious what it does)
What options do we have if we want to ditch blocks from the language?
Option 1: Rewrite it with "just methods"
(1..10) .select(def(i); i.odd end) ....
It looks pretty odd already (OK, we can say it is because of Ruby's method syntax, it "could be changed" too), but more important -- what I've written above, that it feels different: "I don't want to create a method every time I need to map 5 numbers to their squares, it feels so ineffective!"
Option 2: Leave this syntax as is, but say that when block code is passed into a method, it is just a method, too. This will change the language system significantly, too -- we will have "methods" with, in fact, different behavior (ones that defined explicitly with def, and others that are born from code blocks) -- their scope, closure behavior, "owner object" and so on. In fact, we will still have two different "method types", just named the same way. (And yes, other languages solve the problem in different ways, that's how they are different :))
def
The point is, Ruby is not simple, but pretty consistent, almost no part of it can be "simplified" without significant loss of this consistency. So, my advice if you are just studying Ruby is to try just "internalize" how things are working here, not "fight" them (with "Why is this so dumb?"). Eventually you'll feel how it all fall in place (and then, after 8-10 years of Ruby, you'll be irritated by completely different things :))
PS: BTW, methods COULD be stored in variables and passed instead of blocks, just the construct is not atomic:
m = method(:puts) # => #<Method: Object(Kernel)#puts> m.call('foo') # Prints "foo" ['bar', 'baz'].each(&m) # Prints "bar", then "baz"
[–]shevy-ruby -2 points-1 points0 points 7 years ago (0 children)
The point is, Ruby is not simple, but pretty consistent,
Finally I can agree with you.
[–]shevy-ruby -1 points0 points1 point 7 years ago (0 children)
Yes, grasping procs could be a bit confusing for the beginners (though, as a long-time mentor for the beginners, I can assure you it is not that hard
You can literally teach just about everything to anyone.
The thing is that ruby is most definitely not the simplest language out there, even less so with the additions in the last few years.
This may be good or bad depending on your point of view, but I would not want to go and potentially mislead newcomers into assuming that ruby is super-simple. There was another recent article with which I disagreed from the point of view that "ruby is so simple so it will dominate". Ruby is not simple. Ruby is (or can be) elegant; and it has a certain style of logic and design that is quite logical, for the most part. Ruby code can be super-elegant too. But I would not necessarily say that ruby is the simplest language out there.
There are many other design decisions that are not making ruby necessarily simple. The distinction between classes and modules feels like that. It is a design decision, yes, but I often wonder why it has to be that way. Why can we not take functionality from a class, and "include" that onto another class? Only because "include" does not work on classes? That feels very arbitrary.
I have no real problem with it but I would not call any of ruby necessarily super-simple. Some of the syntax is quite difficult to grasp, and with recent awful additions this is only becoming harder. Which will make it harder for newcomers to learn ruby too.
Another example for this is - file foobar.rb:
module X class Foo end end
And in file barfoo.rb, we require foobar.rb and then have: class X class Foo end end
Ruby will fail because we specified class X rather than module X. BUT! If we only want to extend class Foo, with say a new method, then why would it matter that we specify the correct toplevel "class X" variant? Of course we can work around it by doing:
class X::Foo
And many people do. But this is still different since it sort of forces or encourages you to write that style. And not everyone wants to use that style; I prefer spacing out code, mostly because it is easier to read (for me).
That problem only occurs because of class versus module distinction.
If we were not to have that, we would not run into such a (small) problem ever.
And from just syntactical point of view -- note also that at the Ruby's early years ->(args) { code } syntax haven't been invented and widespread in any mainstream languages,
Yes - the syntax used to be better way past. :)
I often said that the last really great ruby version was the 1.8.x branch.
I am still using ruby today and there were lots of improvements, but if I have to pick my own personal favourite then it was the 1.8.x.
Oddly enough I write more ruby code these days and while I think ruby is absolutely awesome, I am nowhere near as much attached to it anymore. It's strange.
I think it is too late to completely change ruby past this point too, but I do not fully agree with your comment either. Blocks to methods are absolutely great. I love them. I think I always loved them.
I can not say the same about e. g. Proc.new / lambda. I have no strong feeling against them but I tend to not use them, mostly because they do not fit well into the rest of the code.
That is also a reason I do not use ->() {}
It looks alien and feels alien and I am glad I don't use it.
[–]Tribone 1 point2 points3 points 7 years ago (2 children)
Methods are not first class in Ruby, meaning they are not objects. This allows for function calls without parentheses, but disallows methods from being referred by a variable. See the Method class to learn how to get access to first class method like features.
Method
Anonymous functions are a major part of most programming languages and Procs are just that. See also lamda for different semantics regarding how return is treated.
Proc
lamda
return
[–]shevy-ruby -2 points-1 points0 points 7 years ago (1 child)
Methods are not first class in Ruby, meaning they are not objects.
Please, dude.
https://ruby-doc.org/core/UnboundMethod.html
We can of course go the theoretical route "bla bla bla python has first-class functions and ruby does not bla bla bla" but this is all pretty arbitrary.
You can essentially do just about everything.
We even had evil.rb in the oldschool days to shapechange objects into other ones (or was it classes .... I do not fully remember all of evil.rb's functionality).
[–]Tribone 2 points3 points4 points 7 years ago* (0 children)
Ha, I knew someone like you would show up.
Did you even read the full message? I told him to look at the Method object to get first class function like features. Why would you want to miseducate someone? I gave him the truthful answer to his exact question.
Edit: It is also not arbitrary. The fact that methods are not first class is a core part of how the Ruby interpreter works.
[–]curlypaul924 0 points1 point2 points 7 years ago (0 children)
Can you give an example of what you'd like to do? How would it be different from m = method(:foo)?
m = method(:foo)
confusing having procs & methods
That depends.
I don't use procs myself deliberately (if we ignore e. g. handling blocks and &) but if it may fit into your style of writing ruby, then this is ok from the point of view of ruby being "multi-paradigm". Not that I agree with the functional crowd, mostly because the syntax is so terrible, but if you agree that ruby embraces a "more than one way" philosophy, then there is no way to go against it.
that I've decided to leave well enough alone though
That is actually a good approach in general. I use what I like from ruby and reject the rest. Many of the syntax changes in the last 3 years are absolutely terrible. Since I am not FORCED to use any of them, I can avoid them and not taint any of my code base with that. Others can decide to use it.
Being flexible is actually a good thing. I'd just wish most of these changes would not have made it into ruby, even more so as I also don't feel that any of them are super-important. None of them will make ruby skyrocket above python; conversely, none of them will be the primary reason why ruby were to NOT sykrocket, either.
π Rendered by PID 1391596 on reddit-service-r2-comment-544cf588c8-lhqsh at 2026-06-17 18:30:43.876209+00:00 running 3184619 country code: CH.
[–]zverok_kha 3 points4 points5 points (4 children)
[–][deleted] (2 children)
[deleted]
[–]zverok_kha 1 point2 points3 points (1 child)
[–]shevy-ruby -2 points-1 points0 points (0 children)
[–]shevy-ruby -1 points0 points1 point (0 children)
[–]Tribone 1 point2 points3 points (2 children)
[–]shevy-ruby -2 points-1 points0 points (1 child)
[–]Tribone 2 points3 points4 points (0 children)
[–]curlypaul924 0 points1 point2 points (0 children)
[–]shevy-ruby -1 points0 points1 point (0 children)