I still feel the question is a little vague. You should also note that I have ignored your example data. Given your example data, the results of both $hash1 and $hash2 are empty hashes.
For your first question:
$hash1[a] ||= {}
The above is a combination of two things
First is an index into a hash which I'll assume you're familiar with.
The second is sort of a conditional assignment. As an example:
blah ||= 1
The above says, assign the value 1 to blah as long as blah is nil. If blah is not nil then the assignment is not performed.
For the if statement we'll need some context:
if $hash1[b] && $hash1[b][a] #if the pair exists reversed
$hash2[a] ||= [] #initialize the array for the second
$hash2[a] << b #append the third to the second's array
$hash2[b] ||= [] #likewise for the reverse
$hash2[b] << a
end
If we assume that the initial values of $hash1 and $hash2 are {} as you note, and if we assume the input are a series of --- delimted values, then given the following data set:
foo---b---c
foo---c---a
foo---a---b
foo---b---a
foo---a---d
foo---d---a
The value of $hash1 would be:
{"a"=>{"b"=>true, "d"=>true}, "b"=>{"a"=>true, "c"=>true}, "c"=>{"a"=>true}, "d"=>{"a"=>true}}
Where $hash2 would be:
{"a"=>["b", "d"], "b"=>["a"], "d"=>["a"]}
Given this, I can make an educated guess that the block of code is generating a dictionary of relationships. In the above, $hash1 lists whether a given value refers to other values. A sort of a truth test. If you wanted to know if A referred to B you could just use:
$hash1['a']['b']
If the result is true then the answer is yes.
$hash2 is a sort of dictionary of two way relationships.
If you checked:
$hash2['a']
You would find an array of all the things to which A refers which also refer to A.
Cheers.