Skip to content

Instantly share code, notes, and snippets.

@johncarney
Last active August 29, 2015 14:24
Show Gist options
  • Select an option

  • Save johncarney/d9af57cd74f57d617d1a to your computer and use it in GitHub Desktop.

Select an option

Save johncarney/d9af57cd74f57d617d1a to your computer and use it in GitHub Desktop.
FlexStruct: Wrapper around Ruby's Struct with a more flexible initializer.

Creating a FlexStruct class

You can create a FlexStruct either by using FlexStruct.new in the same way you would use Struct.new, or you can include it in a class. As with Struct.new, you can provide a class name as the first parameter. When you do this, the named class will exist in the Struct namespace.

# Shorthand
MyClass = FlexStruct.new(:x, :y)

# Included
MyClass = Struct.new(:x, :y) do
  include FlexStruct
end

# Named
FlexStruct.new("Mine", :x, :y)
# => Struct::Mine

Instantiating a FlexStruct class.

FlexStructs can be instantiated using either traditional ordered parameters, or by using keyword parameters, or a mix of both. Note that if you mix initialization styles, the ordered parameters will "trump" keyword parameters.

# Traditional
MyClass.new(1, 2)
# => <struct MyClass x=1, y=2>

# Keyword paramaters
MyClass.new(x: 3, y: 4)
# => <struct MyClass x=3, y=4>

# Mixed
MyClass.new(5, y: 6)
# => <struct MyClass x=5, y=6>

# Ordered parameters trump keyword parameters.
MyClass.new(7, x: 8)
# => <struct MyClass x=7, y=nil>
module FlexStruct
def initialize(*args, **options)
super(*args, *options.values_at(*members[args.length..-1]))
end
def self.new(*args, &block)
Struct.new(*args, &block).include self
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment