If array were large and performance were important you might write the following.
array.group_by(&:class).sort_by { |k,_| k.to_s }.flat_map(&:last)
#=> [{:one=>"one"}, 1, "1", "one", :one, true]
# Hash Integer String String Symbol TrueClass
The steps in the calculation are as follows.
h = array.group_by(&:class)
#=> {Integer=>[1], String=>["1", "one"], TrueClass=>[true],
# Hash=>[{:one=>"one"}], Symbol=>[:one]}
a = h.sort_by { |k,_| k.to_s }
#=> [[Hash, [{:one=>"one"}]], [Integer, [1]], [String, ["1", "one"]],
# [Symbol, [:one]], [TrueClass, [true]]]
a.flat_map(&:last)
#=> [{:one=>"one"}, 1, "1", "one", :one, true]
See Enumerable#group_by, Enumerable#sort_by and Enumerable#flat_map.
Letting n be the number of elements in array and m being the number of unique classes represented by the elements of array, the computation complexities of each component of the calculation are as follows.
group_by(&:class) : O(n)
sort_by { |k,_| k.to_s } : O(m*log(m))
flat_map(&:last) : O(m)
By contrast, a conventional sort has a computational complexity of O(n*log(n)).
For the example of array given in the question,
n = array.size
#=> 6
m = array.map(&:class).uniq.size
#=> 5
Clearly, the conventional method of sorting would be fastest in this case. If, however, n were large and m relatively small, relative computational speed would be determined by O(m*log(m)) versus O(n*log(n)), giving a large advantage to the method I proposed.
Note that this approach could be taken in any situation where elements e of a collection are to be sorted by a method m such that the number of unique values of m(e) is relatively small when compared to the size of the collection.