Closures MultiClosures - UnquietCode/Closures-for-Java GitHub Wiki

MultiClosures are a sort of "Closure collection". A MultiClosure supports 7 run operations, being 0-6 and varargs. Not all of the methods have to be implemented, and one can check for implemented methods by using isImplemented. MultiClosures also have their own views.
Another interesting feature is that a MultiClosure can spawn views for each of its closure types. Further, implementing a vararg method ensures that all run operations will be implicity implemented. See the examples below for more information.

	public void multiclosureBasics() {
		// Multiclosures are like an abstract collection of other closures. They can support 0-6 arguments
		// and vararg. Any method not implemented by you will throw an exception.
		// The vararg method functions as a fallback for any unimplemented versions, if it is itself defined.
		// They support views just like the other classes, and can even offer individual views for each
		// of the closure types 0-6 and the unified ClosureView.

		// Note that here the Overrides are optional, as the class does not require explicitly
		// implementing the methods. It's pick and choose.

		MultiClosure<String> helloMaker = new AbstractMultiClosure() {
			String greeting = "Hello";

			public Object run(Object p1) {
				return greeting + " " + p1;
			}

			public @Override Object run(Object p1, Object p2) {
				return greeting + " " + p1 + " and " + p2;
			}

			public @Override Object run(Object...args) {
				StringBuilder sb = new StringBuilder();
				sb.append(greeting).append(" to");

				int lcv = 0;
				for (Object o : args) {
					String s = (String) o;
					sb.append(" ").append(s);

					if (lcv == args.length-2)
						sb.append(", and");
					else if (lcv < args.length-1)
						sb.append(",");

					++lcv;
				}

				return sb.toString();
			}
		};

		out(helloMaker.run("Bob"));
		out(helloMaker.run("Allan", "Susan"));
		out(helloMaker.run("Jennifer", "Alexander", "Ryan", "Chris"));
		out();


		// We can try to get a more constrained versions of our helloMaker
		Closure1View<String, String> singles = helloMaker.toClosure1();
		out(singles.run("Steven"));

		// Of course, you don't have to type them if you don't want to.
		Closure2View doubles = helloMaker.toClosure2();
		out(doubles.run("Tabitha", "Aragorn"));

		// We didn't define a 3 argument version, but we did define a vararg, so it will work.
		Closure3View<String, String, String, String> fallback = helloMaker.toClosure3();
		out(fallback.run("Arnold", "Julie", "Marissa"));

		// However, if we did not define a vararg version, we would have gotten an exception at runtime!

		// We can curry the MultiClosure too.
		out();
		helloMaker.curry(1, "Goodbye");
		out(helloMaker.run("Bob", "Allan", "Susan", "Jennifer", "Alexander", "Ryan", "Chris"));

		// Remember though that the views are affected.
		out();
		ClosureView closure = helloMaker.toClosure();
		helloMaker.curry(1, "Welcome back");
		out(closure.run("Bob", "Allan", "Susan", "Jennifer", "Alexander", "Ryan", "Chris"));
	}


	public void mcTest() {
		// MultiClosures will let you know which of their methods have been implemented.
		// They must be implemented using Object types in the parameters.
		// Use @Override annotations if that helps.

		MultiClosure<String> helloMaker = new AbstractMultiClosure<String>() {

			public @Override String run(Object p1) {
				return "hello " + p1;
			}

			public @Override String run(Object p1, Object p2) {
				return "hello " + p1 + " and " + p2;
			}

			public String run(String p1) {  // This does NOT override any base methods!
				return "d'oh " + p1;
			}
		};

		// We can figure out what's implemented.
		for (int i = -1; i < 8; ++i) {
			out(i + " : " + helloMaker.isImplemented(i));
		}

		out();
		out(helloMaker.run(1));         // ok
		out(helloMaker.run(1,2));       // fine
		//out(helloMaker.run(1,2,3));   // This will throw an exception (NotImplementedException).
	}
⚠️ **GitHub.com Fallback** ⚠️