# Bug in facets 1.8.54

**URL:** <https://www.ruby-forum.com/t/bug-in-facets-1-8-54/106400>\
**Category:** Ruby\
**Created:** [June 9, 2007, 10:02pm UTC](https://www.ruby-forum.com/t/bug-in-facets-1-8-54/106400 "2007-06-09T22:02:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nasir\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/838e76/32.png) [@Nasir\_K](https://www.ruby-forum.com/u/Nasir_K)\
**Post date:** [June 9, 2007, 10:02pm UTC](https://www.ruby-forum.com/t/bug-in-facets-1-8-54/106400/1 "2007-06-09T22:02:45Z")

</div>

There seems to be a bug in facets PQueue v1.8.54, at least the behavior  
is  
inconsistent. Here is the output on machine-1 which is running -

* * *

ruby 1.8.5 (2006-08-25) [i386-mswin32]  
facets (1.8.51, 1.8.8)

## irb(main):001:0\> require ‘facets/more/pqueue’ =\> true irb(main):002:0\> pqueue = PQueue.new(lambda{|x,y| x\<y}) =\> #\<PQueue:0x2c35c60 @gt=#Proc:0x02c35d28@:2(irb), @size=0, @qarray=[n irb(main):003:0\> irb(main):004:0\* pqueue.top =\> nil

This is the expected behavior

While on another machine with -

* * *

ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]  
facets (1.8.54)

## irb(main):001:0\> require ‘facets/more/pqueue’ =\> true irb(main):002:0\> @pqueue = PQueue.new(lambda{|x,y| x\<y}) c:/ruby/lib/ruby/gems/1.8/gems/facets-1.8.54/lib/facets/more/pqueue.rb:236: warn ing: default `to\_a’ will be obsolete =\> \<PQueue: size=1, top=#Proc:0x02d9bc58@:2(irb)\> irb(main):003:0\> @pqueue.top =\> #Proc:0x02d9bc58@:2(irb)

Strangely the lambda supplied as the comparator is inserted in the  
queue.  
Both Ruby and Facets version is different.

TIA

- nasir

---

<div class="post-metadata">

**Author:** ![Nasir\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/838e76/32.png) [@Nasir\_K](https://www.ruby-forum.com/u/Nasir_K)\
**Post date:** [June 9, 2007, 10:14pm UTC](https://www.ruby-forum.com/t/bug-in-facets-1-8-54/106400/2 "2007-06-09T22:14:49Z")

</div>

Ah! pqueue.rb was changed to be backward incompatible from facets  
1.8.51 -\> 1.8.54

# 1.8.51

def initialize(compareProc=lambda{|x,y| x\>y})  
# By default, retrieves maximal elements first.  
@qarray=[nil]; @size=0; @gt=compareProc; make\_legal  
end

# 1.8.54

def initialize(elements=nil, &block) # :yields: a, b  
@qarray = [nil]  
@size = 0  
@gt = block || lambda {|a,b| a \> b}  
replace(elements) if elements  
end

Is there a way to load 1.8.51 version of one file (in this case  
pqueue.rb) while use rest of the facets gem 1.8.54?  
The other option is to monkey patch ☹  
Any other option?

- nasir

---

<div class="post-metadata">

**Author:** ![Nasir\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/838e76/32.png) [@Nasir\_K](https://www.ruby-forum.com/u/Nasir_K)\
**Post date:** [June 10, 2007, 10:19pm UTC](https://www.ruby-forum.com/t/bug-in-facets-1-8-54/106400/3 "2007-06-10T22:19:11Z")

</div>

Le samedi 09 juin 2007 22:14, Nasir K. a écrit :

> pqueue.rb) while use rest of the facets gem 1.8.54?  
> The other option is to monkey patch ☹  
> Any other option?
> 
> - nasir

Hi,

Yes you are right, pqueue was rewritten and the api changed a lot. In  
Facets,  
there was two different classes for the same purpose, PQueue and Heap,  
which  
both provided a heap based priority queue. The latter was broken,  
although it  
had functionalities that pqueue lacked.

So, I merged both classes into one full-featured class, with a different  
API,  
closer to the Array one and more ruby-like to me. I submitted it, and as  
I  
based my work on pqueue, it replaced the previous version of the class,  
and  
Heap was removed.

Here is the notes I transmitted to Trans, who maintains Facets :

- Initialization can take both initial values and comparison block, both  
optionnaly. Whereas the original PQueue take only a block, and Heap take  
only  
the initial values and needs to be subclassed in order to implement the  
comparison
- Every methods which take an array as a parameter (initialize,  
push\_all,  
replace) can now take any object that responds to #to\_a, and are  
optimized in  
the case where the given object is a PQueue itself.
- Creating a queue from scratch (with #initialize or with #replace) is  
faster  
than for the original PQueue, by adapting the #heapify method from Heap.
- Added consistent methods #inspect, #==, #initialize\_copy.
- Methods are documented and unit-tested.

I dropped some methods from both original classes :

- PQueue#make\_legal, useless since the PQueue is now always legal
- PQueue#replace\_top\_low, which I can’t figure out the purpose 🙂
- PQueue#each\_with\_index, already provided by Enumerator
- Heap#sort\_internal, was like an inplace-sort, but it destroyed the  
PQueue.

Actually, I didn’t know it was already commited 🙂  
If you used only push, pop, clear and empty? in your client code, then  
the  
only api change is for the instanciation method, which doesn’t take a  
Proc  
object as an argument, but a block.

I see no other solution than monkey patching, if you really don’t want  
to  
modify your client code.

Regards

---

<div class="post-metadata">

**Author:** ![Nasir\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/838e76/32.png) [@Nasir\_K](https://www.ruby-forum.com/u/Nasir_K)\
**Post date:** [June 11, 2007, 3:09am UTC](https://www.ruby-forum.com/t/bug-in-facets-1-8-54/106400/4 "2007-06-11T03:09:36Z")

</div>

Thanks Olivier.  
IMHO def initialize(compareProc=lambda{|x,y| x\>y}, elements=nil)  
could have preserved backwards compatibility for PQueue users and also  
preserved semantics of passing the comparator as an argument rather than  
a  
block.  
Shall work around for now.

Thanks  
Nasir
