# 6 | Modifying Arguments

### What is ModifyArg?

Consider the following method

```java
private void aMethod() {
    System.out.println("No. 4561!");
    System.out.println("HElooo 25!");
    System.out.println("idk 356!");
    System.out.println("interesting 46!");
    System.out.println("Hi! 5!");
    System.out.println("Hello 1!");
    System.out.println("no? 456!");
    System.out.println("Bye 48!");
    System.out.println("ALLRIGHt 33!");
    System.out.println("lol 10!");
}
```

As you can clearly observe, it consists of a set print statements, which outputs 10 strings with no noticeable pattern.

So, what if I wanted to change the text `"Hi! 5!"` to `"Hello world!"`?

With our current knowledge all we could do is `@Overwrite` it, but this becomes very painful with larger method bodies with functions/variables that need `@Shadow`'ing (I will talk about shadowing later)

So what do we do?

May I introduce you to `@ModifyArg`; a neat function that allows us to modify the arguments of a method in a function

In the example provided, we can use `@ModifyArg` like so

```java
@ModifyArg(method = "aMethod", at = @At(
            value = "INVOKE",
            target = "Ljava/io/PrintStream;println(Ljava/lang/String;)V",
            ordinal = 4),
           index = 0)
private String modifyOutput(String x) {
    return "Hello World!";
}
```

Since we've already covered most of what's going on inside that annotation, all we need to cover is the `ordinal` and the `index` .

* `ordinal = 4` (optional)
  * This allows you to set an offset of which `println` statement you actually want to modify, indexed by zero, in this case, it was set to 4, meaning that the 4th zero indexed println statement's arguments will be modified
* `index = 0`
  * This is the last parameter that we have set, which isn't inside the `@At` statement, this allows us to select which argument in the function we want to modify (indexed by zero)

Lastly, the return statement, `return "Hello World!"`, just returns what we want that argument to be

### Modify Arg cont. <a href="#more-context" id="more-context"></a>

What happens if the argument we want to modify depends on all of the other arguments being passed in?

Say, instead of `println` accepting 1 argument (`String`), rather, it accepted 2 arguments, your message, and the number of times you want it to be printed

```java
private void aMethod() {
    System.out.println("No. 4561!", 5);
    System.out.println("HElooo 25!", 3);
    System.out.println("idk 356!", 45);
    System.out.println("interesting 46!", 34);
    System.out.println("Hi! 5!", 34);
    System.out.println("Hello 1!", 42);
    System.out.println("no? 456!", 4);
    System.out.println("Bye 48!", 1);
    System.out.println("ALLRIGHt 33!", 99);
    System.out.println("lol 10!", 27);
}
```

In this example, once again, we want to change the text of `"Hi! 5!"` to `"Hello world!"`, but this time we also want to add the number of times it will repeat to it (ie: `"Hello World! (34)"`)

It's as simple as adding the extra arguments to the function, like shown below

```java
@ModifyArg(method = "aMethod", at = @At(
            value = "INVOKE",
            target = "Ljava/io/PrintStream;println(Ljava/lang/String;I)V",
            ordinal = 4),
           index = 0)
private String modifyOutput(String x, int nTimesToRepeat) {
    return "Hello World! (" + nTimesToRepeat + ")";
}
```

### ModifyArg vs Modify Args <a href="#what-is-modifyargs" id="what-is-modifyargs"></a>

While going through this tutorial, you might've noticed that there's another annotation called `ModifyArgs` instead of `ModifyArg` . So, what's the difference?

Well, using the former example where `println` has 2 arguments, a message and a number of times to print that message, we can modify multiple arguments like so

```java
@ModifyArgs(method = "aMethod", at = @At(
            value = "INVOKE",
            target = "Ljava/io/PrintStream;println(Ljava/lang/String;I)V",
            ordinal = 4))
private void modifyOutput(Args args) {
    String x = args.get(0);
    int nTimesToRepeat = args.get(1);

    args.set(0, "Hello world! (" + nTimesToRepeat + ")");
    args.set(1, nTimesToRepeat + 20);
}
```

Args? What's that?

`Args` is a class provided by `Mixin` that provides 2 major methods

* `args.get(int index)`
  * This allows you to retrieve one of the function's arguments be index
* `args.set(int index, T value)`
  * This allows you to set an arguments value by index

An annotated example of `ModifyArgs` is shown below

```java
String x = args.get(0); // Get the first argument, the string
int nTimesToRepeat = args.get(1); // Get the second argument, the number of times to repeat the message

args.set(0, "Hello world! (" + nTimesToRepeat + ")"); // Set the first argument to the string "Hello world! (n)", with n being the number of times to repeat
args.set(1, nTimesToRepeat + 20); // This takes the number of times to repeat, and adds the value 20 to it
```

###


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ddozzi.gitbook.io/mixin-tutorial/how-to-make-a-mixin-client/7-or-modifying-arguments.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
