Struct vs. OpenStruct definition

With Struct and OpenStruct objects can be created whose structure is determined at runtime. Their flexibility allows data to be structured without creating equal classes. Especially since the instantiation of Struct objects consumes even less performance compared to classes.
So Structs should be considered.

Struct

Whenever data is related to each other or share the same context, it makes sense to also group it into a structure.
For example, geo data consist of latitude and longitude. Linking them together is more than obvious:

Struct.new 'Geolocation', :latitude, :longitude
geolocation = Struct::Geolocation.new 53.6, 11.4
# => #<struct Struct::Geolocation latitude=53.6, longitude=11.4>
geolocation.latitude # => 53.6
geolocation.longitude # => 11.4

Structs can be created in a variety of ways. Other notations:

# Assignment
Geolocation = Struct.new :latitude, :longitude

# Inheritance
class Geolocation < Struct.new(:latitude, :longitude)
end

It is because Struct#new returns a class.
In addition, structures can also contain logic:

Struct.new(:latitude, :longitude) do
  def east_of_greenwich?
    longitude.positive?
  end
end

OpenStruct

OpenStructs are not as performing as structures, but more flexible. However, they do not belong to the Ruby core:

require 'ostruct'

geolocation = OpenStruct.new latitude: 53.6, longitude: 11.4
geolocation.zoom # => nil
geolocation.zoom = 14
geolocation.zoom # => 14

On the one hand, an instance can be created without defining the structure, and on the other hand the instance also seems to respond to undefined methods. The reason is that OpenStruct Is based on a Hash, and #method_missing captures missing method definitions and creates them at runtime.
This can be helpful in quickly mocking experimental objects or test doubles.