Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.ruby > #2385 > unrolled thread
| Started by | Adam Prescott <adam@aprescott.com> |
|---|---|
| First post | 2011-04-06 08:11 -0500 |
| Last post | 2011-04-06 19:45 -0500 |
| Articles | 7 — 3 participants |
Back to article view | Back to comp.lang.ruby
Proc#== behaviour (from Ruby-Core) Adam Prescott <adam@aprescott.com> - 2011-04-06 08:11 -0500
Re: Proc#== behaviour (from Ruby-Core) Adam Prescott <adam@aprescott.com> - 2011-04-06 15:20 -0500
Re: Proc#== behaviour (from Ruby-Core) Gary Wright <gwtmp01@mac.com> - 2011-04-06 15:50 -0500
Re: Proc#== behaviour (from Ruby-Core) 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-06 18:17 -0500
Re: Proc#== behaviour (from Ruby-Core) Adam Prescott <adam@aprescott.com> - 2011-04-06 18:41 -0500
Re: Proc#== behaviour (from Ruby-Core) Gary Wright <gwtmp01@mac.com> - 2011-04-06 19:52 -0500
Re: Proc#== behaviour (from Ruby-Core) Gary Wright <gwtmp01@mac.com> - 2011-04-06 19:45 -0500
| From | Adam Prescott <adam@aprescott.com> |
|---|---|
| Date | 2011-04-06 08:11 -0500 |
| Subject | Proc#== behaviour (from Ruby-Core) |
| Message-ID | <BANLkTimwasjyAVmRQDAc8U1hm3qTp6fiaA@mail.gmail.com> |
[Note: parts of this message were removed to make it a legal post.] I did ask this question on Ruby-Core a few days ago, but no-one has replied back, so I thought it might get more love here. (Perhaps I'm being stupid.) I'll just copy it verbatim from there. If cross-posting it is wholly objectional, I'm happy to wait, although this problem is holding up some of my code. -- I've encountered a problem when using Proc#== (with both lambdas and procs) in my code, where the result does not match up with what the documentation says. 1.9.2 differs from 1.8.7 in result and in the source code, so that suggests attention has been given to the method, at least. It was suggested that ruby-core was the place to go for this. Here's a paste of the problem, with full RUBY_DESCRIPTIONs: https://gist.github.com/899026 I've included lambda, proc, and Proc.new variants just for completion, even though I realise proc is an alias for lambda or Proc.new, depending. At the very least, perhaps someone could explain why this is by design, if it's not a bug. Apologies if there's an open issue for this on redmine; the site is currently not working for me (again), and I couldn't find anything online mentioning this.
[toc] | [next] | [standalone]
| From | Adam Prescott <adam@aprescott.com> |
|---|---|
| Date | 2011-04-06 15:20 -0500 |
| Message-ID | <BANLkTikAkf1OVNtbuS97o+787oMSP0_-rw@mail.gmail.com> |
| In reply to | #2385 |
[Note: parts of this message were removed to make it a legal post.] I decided to just do what I should've done in the first place, and open an issue on Redmine: http://redmine.ruby-lang.org/issues/4559
[toc] | [prev] | [next] | [standalone]
| From | Gary Wright <gwtmp01@mac.com> |
|---|---|
| Date | 2011-04-06 15:50 -0500 |
| Message-ID | <6EB5399A-D3C6-4478-BFFD-2FE3385886FA@mac.com> |
| In reply to | #2385 |
On Apr 6, 2011, at 9:11 AM, Adam Prescott wrote:
> I've encountered a problem when using Proc#== (with both lambdas and procs)
> in my code, where the result does not match up with what the documentation
> says. 1.9.2 differs from 1.8.7 in result and in the source code, so that
> suggests attention has been given to the method, at least. It was suggested
> that ruby-core was the place to go for this.
I've run into this issue in the past. One of the issues is that the binding associated with a proc can be different even if the 'source' of the binding is the same. I think that is enough to ensure that the proc's won't be considered equal via ==.
You can dup or clone a proc in 1.9.2 to get equivalent procs even though the bindings still aren't equal:
l1 =ruby-1.9.2-p180 > l1 = lambda { 1 + 1 }
=> #<Proc:0x8aa8a4@(irb):1 (lambda)>
ruby-1.9.2-p180 > l2 = lambda { 1 + 1 }
=> #<Proc:0x87a848@(irb):2 (lambda)>
ruby-1.9.2-p180 > l1 == l2
=> false
ruby-1.9.2-p180 > l3 = l1.clone
=> #<Proc:0x8759ec@(irb):1 (lambda)>
ruby-1.9.2-p180 > l1 == l3
=> true
ruby-1.9.2-p180 > l1.binding == l3.binding
=> false
I don't really have a conclusion, just wanted to point out the binding issue and the dup/clone behavior.
Gary Wright
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-06 18:17 -0500 |
| Message-ID | <34d1c3c5c9dcfc298d570bc629187042@ruby-forum.com> |
| In reply to | #2385 |
In case you didn't know, procs and lambdas in ruby are a mess. -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Adam Prescott <adam@aprescott.com> |
|---|---|
| Date | 2011-04-06 18:41 -0500 |
| Message-ID | <BANLkTikL8et4TWOmy5ErKs-Bsm30ePNrUQ@mail.gmail.com> |
| In reply to | #2415 |
[Note: parts of this message were removed to make it a legal post.] On Thu, Apr 7, 2011 at 12:17 AM, 7stud -- <bbxx789_05ss@yahoo.com> wrote: > In case you didn't know, procs and lambdas in ruby are a mess. > I knew, at least, ever since I read http://innig.net/software/ruby/closures-in-ruby.rb I didn't think something like equality would be broken though...
[toc] | [prev] | [next] | [standalone]
| From | Gary Wright <gwtmp01@mac.com> |
|---|---|
| Date | 2011-04-06 19:52 -0500 |
| Message-ID | <B30AD8CD-7B80-49F4-AC00-39B24AB877B3@mac.com> |
| In reply to | #2417 |
[Note: parts of this message were removed to make it a legal post.]
On Apr 6, 2011, at 8:45 PM, Gary Wright wrote:
>
> 3.times { puts 'hip, hip, hooray!' }
> 3.times do puts 'hip, hip, horray! }
-----------------------------------------------^^^^^
That should have been 'end' not '}'
Gary Wright
[toc] | [prev] | [next] | [standalone]
| From | Gary Wright <gwtmp01@mac.com> |
|---|---|
| Date | 2011-04-06 19:45 -0500 |
| Message-ID | <988D57A9-7A3C-42EA-ACC4-C40CDBFB7CC7@mac.com> |
| In reply to | #2417 |
On Apr 6, 2011, at 7:41 PM, Adam Prescott wrote:
> On Thu, Apr 7, 2011 at 12:17 AM, 7stud -- <bbxx789_05ss@yahoo.com> wrote:
>
>> In case you didn't know, procs and lambdas in ruby are a mess.
>>
>
> I knew, at least, ever since I read
> http://innig.net/software/ruby/closures-in-ruby.rb
Interesting read but it seems like the author creates a bit more confusion than is necessary.
That article repeats the common inaccuracy of treating blocks as instances of Proc, but this is a category error. The two things are related but not the same thing at all. I think it clarifies things to view the term 'block' as a describing a syntactic element of a method call and not as an instance of Proc. The syntactic element can get reified into in a instance of Proc (or not) but the syntactic representation is not itself an instance of Proc.
An analogy would be the difference between a literal integer and a fixnum instance:
f1 = 16
f2 = 0xf
f3 = 0b10000
Here are three different syntactic representations of a single fixnum reference. The sequence of characters '16' is not an instance of Fixnum, nor is '0xf' or '0b10000'. The literals cause the runtime to produce a reference to an instance of Fixnum but the syntactical elements are not themselves objects.
Similarly for blocks:
3.times { puts 'hip, hip, hooray!' }
3.times do puts 'hip, hip, horray! }
The blocks are syntactically part of the method call to times and are not themselves instances of Proc. And in the following:
proc { #block }
lambda { #block }
Proc.new { #block}
The 'magic' is happening in the method calls themselves and not in the syntactic structure of the method calls, which is completely standard.
In the referenced article, the author starts off with:
> But then I found out that a
> function can't accept multiple blocks -- violating the principle that closures
> can be passed around freely as values.
The author's terminology is creating more complexity and perhaps confusion than is warranted. It is true that a method call can only have a single block in the same way that a method call can only have a single argument list. They are both syntactical constructs of a method call (blocks and argument lists).
It is not true that a method can not manipulate multiple closures (instances of a Proc):
def compose(f1, f2, arg)
f1.call(f2.call(arg))
end
puts compose( lambda {|x| x * 2 }, lambda { |y| y + 1 }, 10 )
Ruby happens to provide a special syntax for creating and passing a single closure to a method (i.e. the block syntax) but that doesn't prevent you from creating and passing multiple closures to a method if that is what is desired.
The key point I'm trying to make is that it clarifies things to think of 'block' as a syntactical term and to think of 'closure' or 'instance of a Proc' as the actual object that is being manipulated (i.e. passed around, called, queried and so on).
When you look at a method that explicitly captures a block:
def iterate(a1, a2, &b)
[a1,a2].each(&b)
end
It is again important to think of '&' as a syntactical construct in the same way that the parens and commas are part of the syntax of the formal argument list or of an actual method call. The & isn't some strange operator that converts or manipulates the proc instances referenced by b, it is simply a syntactical marker for the block element of the method syntax.
Gary Wright
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.ruby
csiph-web