In Delphi, my native tongue, a rule I follow is, "whoever creates an object
is responsible for freeing it." Now, it's natural to write a function like
so:
function ParseString(AString, ADelimiter: string): TStringList;
begin
Result := TStringList.Create;
// for each delimited string do
Result.Add(StringFragment);
end;
... but I don't like this because the calling function is then responsible
for making sure the resulting TStringList is freed:
procedure DoStuff;
var
AStringList: TStringList;
begin
AStringList := ParseString(MyString, ';');
// do stuff with AStringList
// remember to free AStringList, even though you didn't explicitly create
it
AStringList.Free;
end;
So, to obey the rule of "whoever creates it, frees it," I rewrite the code
to the following:
procedure ParseString(AString, ADelimiter: string; AStringList:
TStringList);
begin
// for each delimited string do
Result.Add(StringFragment);
end;
procedure DoStuff;
var
AStringList: TStringList;
begin
AStringList := TStringList.Create;
try
AStringList := ParseString(MyString, ';', AStringList);
// do stuff with AStringList
finally
AStringList.Free;
end;
end;
Now DoStuff is creating and freeing the object, it's clearer, harder to
overlook the potential memory leak.
So, on to Ruby. This whole issue is not a problem due to garbage collection
... so which way would be the "Right Way" to do this? I'm leaning towards
the original design:
# newbie alert <g>
def parseString(aString, aDelimiter)
strings = Array.new
# do stuff I haven't learned yet
end
v.
def parseString(aString, aDelimiter, aArray)
# do stuff I haven't learned yet
end
Chris