Mocking Sort With Mocha - ruby

How can I mock an array's sort expect a lambda expression?
This is a trivial example of my problem:
# initializing the data
l = lambda { |a,b| a <=> b }
array = [ 1, 2, 3, 4, 5 ]
sorted_array = [ 2, 3, 8, 9, 1]
# I expect that sort will be called using the lambda as a parameter
array.expects(:sort).with( l ).returns( sorted_array )
# perform the sort using the lambda expression
temp = array.sort{|a,b| l.call(a,b) }
Now, at first I expected that this would work; however, I got the following error:
- expected exactly once, not yet invoked: [ 1, 2, 3, 4, 5 ].sort(#<Proc:0xb665eb48>)
I realize that this will not work because l is not passed as a parameter to l. However, is there another way to do what this code is trying to accomplish?
NOTE: I have figured out how to solve my issue without figuring out how to do the above. I will leave this open just in case someone else has a similar problem.
Cheers,
Joseph

Mocking methods with blocks can be quite confusing. One of the keys is to be clear about what behaviour you want to test. I can't tell from your sample code exactly what it is that you want to test. However, you might find the documentation for Mocha::Expectation#yields (or even Mocha::Expectation#multiple_yields) useful.

Related

Nested for loops in Pari/GP

Is there a way to nest for loops inside other for loops in Pari/GP (2.7.6) since the following error always appears:
*** at top-level: read("prog.txt")
*** ^----------------
*** read: sorry, embedded braces (in parser) is not yet implemented.
Code:
(12:14) gp > n = 12
%12 = 12
(12:14) gp > k = 10
%13 = 10
(12:14) gp > g = [1..10]
%14 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
{
forprime(p = 1, 16,
rn = n%p
rk = k%p
{
for(i=1, #g,
if( (rn*(g[i]+rk)+1)%p!=0,
h = concat(h, g[i])
}
g = h
}
Thanks for help. The question where I posted and got the code from got deleted, so I'm kind of stuck at this point.
Braces don't mean the same thing as in C# or many other programming languages. They do not start/end a block.
In PARI multiple statements are joined with a semi-colon and contained within the argument parenthesis of a function. Special functions include while, for, if etc.
For example:
my(s=7);forprime(p=1, 7, s*=3; for(i=1, p, s+=p^2); s+=6); s
contains three statements inside the forprime loop, separated by semicolons and one of those is another loop.
Now braces {} on the other hand, just allow you to write programs that are more than one line long. Normally when an end of line is reached, PARI tries to interpret everything on that line. But it doesn't do that if between { and }, so you never need more than one pair.
In your example you need to remove the inner {} and add some semi-colons between statements.

method cascading is possible here?

I have a three lines of code here like shown below
local = headers.zip(*data_rows).transpose
local = local[1..-1].map {|dataRow| local[0].zip(dataRow).to_h}
p local
Now if you watch the above three lines, I have to store the result of the first line in the variable called local since it would be used in two places in the second line as I have shown,So Can't I cascade the second line with first line anyway? I tried using tap like this
local = headers.zip(*data_rows).transpose.tap{|h|h[1..-1].map {|dataRow| h[0].zip(dataRow).to_h}}
tap is returning the self as explained in the document so can't I get the result final result when I use tab? Anyway other way to achieve this result in one single line so that I don't have to use local variable?
If you're on Ruby 2.5.0 or later, you can use yield_self for this.
local = headers.zip(*data_rows).transpose.yield_self { |h| h[1..-1].map { |dataRow| h[0].zip(dataRow).to_h } }
yield_self is similar to tap in that they both yield self to the block. The difference is in what is returned by each of the two methods.
Object#tap yields self to the block and then returns self. Kernel#yield_self yields self to the block and then returns the result of the block.
Here's an answer to a previous question where I gave a couple of further examples of where each of these method can be useful.
It's often helpful to execute working code with data, to better understand what is to be computed. Seeing transpose and zip, which are often interchangeable, used together, was a clue that a simplification might be possible (a = [1,2,3]; b = [4,5,6]; a.zip(b) => [[1, 4], [2, 5], [3, 6]] <= [a,b].transpose).
Here's my data:
headers=[1,2,3]
data_rows=[[11,12,13],[21,22,23],[31,32,33],[41,42,43]]
and here's what the working code returns:
local = headers.zip(*data_rows).transpose
local[1..-1].map {|dataRow| local[0].zip(dataRow).to_h}
#=> [{1=>11, 2=>12, 3=>13}, {1=>21, 2=>22, 3=>23},
# {1=>31, 2=>32, 3=>33}, {1=>41, 2=>42, 3=>43}]
It would seem that this might be computed more simply:
data_rows.map { |row| headers.zip(row).to_h }
#=> [{1=>11, 2=>12, 3=>13}, {1=>21, 2=>22, 3=>23},
# {1=>31, 2=>32, 3=>33}, {1=>41, 2=>42, 3=>43}]

Can I count on partition preserving order?

Say I have a sorted Array, such as this:
myArray = [1, 2, 3, 4, 5, 6]
Suppose I call Enumerable#partition on it:
p myArray.partition(&:odd?)
Must the output always be the following?
[[1, 3, 5], [2, 4, 6]]
The documentation doesn't state this; this is what it says:
partition { |obj| block } → [ true_array, false_array ]
partition → an_enumerator
Returns two arrays, the first containing the elements of enum for which the block evaluates to true, the second containing the rest.
If no block is given, an enumerator is returned instead.
But it seems logical to assume partition works this way.
Through testing Matz's interpreter, it appears to be the case that the output works like this, and it makes full sense for it to be like this. However, can I count on partition working this way regardless of the Ruby version or interpreter?
Note: I made implementation-agnostic because I couldn't find any other tag that describes my concern. Feel free to change the tag to something better if you know about it.
No, you can't rely on the order. The reason is parallelism.
A traditional serial implementation of partition would loop through each element of the array evaluating the block one at a time in order. As each call to odd returns, it's immediately pushed into the appropriate true or false array.
Now imagine an implementation which takes advantage of multiple CPU cores. It still iterates through the array in order, but each call to odd can return out of order. odd(myArray[2]) might return before odd(myArray[0]) resulting in [[3, 1, 5], [2, 4, 6]].
List processing idioms such as partition which run a list through a function (most of Enumerable) benefit greatly from parallel processing, and most computers these days have multiple cores. I wouldn't be surprised if a future Ruby implementation took advantage of this. The writers of the API documentation for Enumerable likely carefully omitted any mention of process ordering to leave this optimization possibility open.
The documentation makes no explicit mention of this, but judging from the official code, it does retain ordering:
static VALUE
partition_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arys))
{
struct MEMO *memo = MEMO_CAST(arys);
VALUE ary;
ENUM_WANT_SVALUE();
if (RTEST(enum_yield(argc, i))) {
ary = memo->v1;
}
else {
ary = memo->v2;
}
rb_ary_push(ary, i);
return Qnil;
}
This code gets called from the public interface.
Essentially, the ordering in which your enumerable emits objects gets retained with the above logic.

recursion in prolog - error in base case

I'm trying to write predicate range\3 that takes three parameters the first is the start, the second is the end and return the generated list in the third argument.
E.g rang(1,5,L).
L = [1, 2, 3, 4, 5]
I used this code
range(E,E,[E]).
range(S,E,L):-
S1 is S + 1,
range(S1,E,[S|L]).
But it does not work, when i used trace command to know where is the error i recognized that the base case is useless, I also tried the green cut !in the base case but it does not work range(E,E,[E]),!.
So, if any one knows what is the problem please help me
You're building the list in 'wrong' sense. Consider that when you'll call the base case, it will receive the consed list. How could match a single element list ? Try instead
range(S,E,[S|L]):-
S1 is S + 1,
range(S1,E,L).

Ruby: What is a simple way of searching for certain criteria in an array?

I have an array which I want to make sure all the numbers are between 1 and 6. Here is my array:
guess = [2, 5, 6, 8]
Or something like that. The user inputs the sequence. Anyway, I want a way to check it, and if the numbers aren't all between 1 and 6, it won't break out of the loop. And also could it please be simple!
guess.all?{|i| (1..6).include?(i)}
guess.count{|i| i.between?(1,6)} == guess.size

Resources