However passing by reference is more explicit, but that then introduces in the issue of 'dirtying' your arguments which is generally agreed to be avoided if possible. I believe the reasoning is that entering a function shouldn't modify the state of your program, although this can usually be ignored with more complex data e.g throwing around hashes is potentially pricey.

I could push everything into a seperate data type, but wouldn't that make things a little less clear and require "not necessary" lines of code?

At the worst it will require a line or two of code, but organising your data is far more likely to *reduce* your code. Let's take send_mail() for example. Currently you have 8 arguments, whereas I'd probably reduce that to 2 arguments with all the sendmail-related information in a hash or even a hash of hashes. But then again I think that all this throwing about of data is a symptom of a mis-organised program, to which I think part of the solution would be re-structuring the data as once you have well-defined data structures the program tends to follow.
HTH