pkperl has asked for the wisdom of the Perl Monks concerning the following question:
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Array or Hash Reference to Subroutine
by AR (Friar) on Apr 29, 2010 at 19:28 UTC | |
If I understand you correctly, you are asking why would someone pass an array or hash reference to a subroutine. There are two reasons I can think of immediately: passing multiple distinct arrays/hashes to a subroutine and passing an array or hash that you want to manipulate in the subroutine. If you pass multiple arrays into a subroutine, there's no way to distinguish where one ends and the next begins. That's why you would pass them as references. If your subroutine adds or removes elements from the hash or array and you want that to be reflected when the subroutine ends, you must pass by reference. Edit: Here's some code to show what I mean.
| [reply] [d/l] |
|
Re: Array or Hash Reference to Subroutine
by toolic (Bishop) on Apr 29, 2010 at 19:42 UTC | |
| [reply] |
|
Re: Array or Hash Reference to Subroutine
by ikegami (Patriarch) on Apr 29, 2010 at 20:23 UTC | |
Since one often has to use references, it's not a bad idea to default to passing a reference. At least, that's the reason I do it. It gets confusing if you're not consistent. | [reply] [d/l] [select] |
|
Re: Array or Hash Reference to Subroutine
by talexb (Chancellor) on Apr 29, 2010 at 20:48 UTC | |
Pass by reference is preferred over pass by value when making a call to a subroutine, because at the lowest level it means a data pointer is passed on the call stack, rather than a copy of the contents of that data pointer. This makes a difference because it takes time and space to copy data from a local location to a stack before the call, and more time and space to copy data from the stack to another local location. You can save time and space at both ends by just using a pointer, at the slight cost of additional complexity. The complexity is well-hidden in Perl (and other high level languages); we just add a single character to indicate the indirection in the subroutine call, and understand that we'll be dealing with a reference in the subroutine. Once you are more experienced in writing code, this will come very easily to you. | [reply] |
by ikegami (Patriarch) on Apr 29, 2010 at 22:13 UTC | |
You seem to be confusing passing by reference with passing a reference. Perl always passes by reference, whether what you are passing is a reference or not. On the other hand, a sub that starts with my (...) = @_; or similar effectively causes Perl to pass by value, even when you pass a reference. The difference is not between passing by reference and passing by value. The difference in the size of the list being passed. When passing a reference to an array to a sub, only one argument is placed on the stack. When passing an array's contents to a sub, as many arguments are placed on the stack as there are elements in the array. Seeing as the latter is done using a simple memcpy, performance should not be an issue. And it isn't. Using the reference is actually 9% slower for a typical array (N=10)!
Even for very large arrays, the performance of just passing the array's elements is quite good. Passing all 10,000 elements of an array is only 14% slower than passing the reference alone!
Performance gains is obviously not the reason passing references is done. (Although perceived performance gains could be.) (I included a trivial load to get more reasonable numbers.) Benchmark code: Read more... (834 Bytes)
| [reply] [d/l] [select] |