Вот подход, при котором вы передаете список идентификаторов, связанных с каждым уровнем вложенности:
def classify(o, with)
case o
when Hash
h = {}
o.each {|k,v| h[:"#{with[0]}:#{k}"] = classify(v, with[1, with.length])}
h
else
o.class
end
end
hash = {:UserTicket=>'123',:ImpersonationUsername=>'dave',:TicketSettings=>{:ResourceId=>'abcd',:ClientIp=>'0',:Username=>'bobby'}}
classify(hash, [ :mes, :data ])
# => {"mes:UserTicket"=>String, "mes:ImpersonationUsername"=>String, "mes:TicketSettings"=>{"data:ResourceId"=>String, "data:ClientIp"=>String, "data:Username"=>String}}
Если вы используете рекурсивный алгоритм, у вас есть возможность изменить область применения того, что применяется с каждым уровнем, который вы копаете.