hardayal / hamcrest

Automatically exported from code.google.com/p/hamcrest
0 stars 0 forks source link

First parameter of allOf, anyOf, etc. has the type tied down too much #92

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
At the moment, in classes such as AllOf and AnyOf, the static methods have
the first parameter with the type of Matcher<T>, for instance:

public static <T> Matcher<T> allOf(Matcher<T> first, Matcher<? super T> second)

Would the signature

public static <T> Matcher<T> allOf(Matcher<? super T> first, Matcher<?
super T> second)

not give the same type safety, as well as allowing more flexible calls?

Original issue reported on code.google.com by mikerwil...@yahoo.co.uk on 27 Jun 2009 at 8:19

GoogleCodeExporter commented 8 years ago
It turns out in practice that the first argument needs to be more narrowly 
typed to get the return type to work. If 
it's really a problem, you could change the order since they're all applied.

Original comment by smgfree...@gmail.com on 27 Jun 2009 at 8:42

GoogleCodeExporter commented 8 years ago
It turns out in practice that the first argument needs to be more narrowly 
typed to get the return type to work. If 
it's really a problem, you could change the order since they're all applied.

Original comment by smgfree...@gmail.com on 27 Jun 2009 at 8:42

GoogleCodeExporter commented 8 years ago
I'm not sure I follow your argument. Let's take an example: say we want to 
assert
that the value of some String is either "foo" or "bar". As I understand, the
assertion would like:

  assertThat(string, anyOf(equalTo("foo"), equalTo("bar")));

Now, doing this using the existing anyOf implementation causes the unsafe 
varargs
version to be used since the return type of equalTo is Matcher<? super T> 
(where T is
String in this case), and so the (type-safe) two argument version of anyOf 
cannot be
used.

However, the function:

  public static <T> Matcher<T> allOf(Matcher<? super T> first, Matcher<? super T>
second) {
    List<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>();
    matchers.add(first);
    matchers.add(second);
    return new AllOf<T>(matchers);
  }

would allow these two arguments, and correctly determines the return type.

In this case, I also don't see how changing the order would help.

Original comment by mikerwil...@yahoo.co.uk on 27 Jun 2009 at 9:16