Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an easier alternative to mimicking the splat operator?

I've found it's available in Ruby, but I recognize it from what I've done in Python; the "splat" operator. Long story short, I'm wondering if there's a simpler way to accomplish what I currently am, mimicking what the "splat" operator does.

I made a central method that the rest can call because I realized I have several very similar ones, and they were all doing the same except for a few minor things. Here's the method signature:

private String callScript(String scriptLocation, String... extraArgs) throws Exception {

I want to require at least one argument (the scriptLocation), and then allow any number of extra arguments. What I end up doing with this is creating a ProcessBuilder. My desire is to do something like this:

ProcessBuilder pb = new ProcessBuilder("something", scriptLocation, /* extraArgs */);

But of course, the ProcessBuilder constructor only accepts things like:

  • List<String>
  • String[]
  • String...

So my approach obviously wouldn't work.

My current workaround, which works fine as far as I know, is:

List<String> finalArgs = new ArrayList<String>();
finalArgs.add("something");
finalArgs.add(scriptLocation);
finalArgs.addAll(Arrays.asList(extraArgs));
ProcessBuilder pb = new ProcessBuilder(finalArgs);

(yes, I understand I don't have to use List and could just make a String[])

(and yes, I understand I could loop through extraArgs and add them to finalArgs individually, instead of having to use addAll and Arrays.asList())

(and yes, I know I can make a function that effectively accomplishes my workaround by returning certain arguments combined with variable arguments)

So I guess outside of these last three statements, is there anything that can achieve this?

like image 599
Ian Avatar asked Jul 27 '13 00:07

Ian


1 Answers

It depends on your definition of simpler, but you could write a class utilizing the Builder pattern:

public class MyProcessBuilder {
    List<String> args;

    MyProcessBuilder( String text, String location ) {
        args = new ArrayList<String>();
        args.add( text );
        args.add( location );
    }

    MyProcessBuilder arg( String arg ) {
        args.add( arg );
        return this;
    }

    MyProcessBuilder args( String... args ) {
        this.args.addAll( Arrays.asList( args ) );
        return this;
    }

    public ProcessBuilder go() {
        return new ProcessBuilder( args );
    }

    public static MyProcessBuilder callScript( String location ) {
        return new MyProcessBuilder( "something", location );
    }

    public static void main( String[] args ) {
        callScript( "/tmp/bla" ).arg( "something else" ).arg( "more" ).go();
    }
}
like image 150
achimh Avatar answered Oct 07 '22 07:10

achimh