A named tuple is a fixed-size, immutable, stack-allocated mapping of a fixed set of keys to values.
You can think of a NamedTuple as an immutable Hash whose keys (which are of type Symbol), and the types for each key, are known at compile time.
A named tuple can be created with a named tuple literal:
language = {name: "Crystal", year: 2011} # NamedTuple(name: String, year: Int32)
language[:name] # => "Crystal"
language[:year] # => 2011
language[:other] # compile time error See NamedTuple literals in the language reference.
The compiler knows what types are in each key, so when indexing a named tuple with a symbol or string literal the compiler will return the value for that key and with the expected type, like in the above snippet. Indexing with a symbol or string literal for which there's no key will give a compile-time error.
Indexing with a symbol or string that is only known at runtime will return a value whose type is the union of all the types in the named tuple, and might raise KeyError.
Indexing with #[]? does not make the return value nilable if the key is known to exist:
language = {name: "Crystal", year: 2011}
language[:name]? # => "Crystal"
typeof(language[:name]?) # => String NamedTuple's own instance classes may also be indexed in a similar manner, returning their value types instead:
tuple = NamedTuple(name: String, year: Int32) tuple[:name] # => String tuple["year"] # => Int32 tuple[:other]? # => nil
Creates a named tuple from the given hash, with elements casted to the given types.
Creates a named tuple that will contain the given arguments.
Returns the value type for the given key if there is such a key, otherwise raises KeyError.
Returns the value type for the given key if there is such a key, otherwise returns nil.
Returns the types of this named tuple type.
Returns true if this tuple has the same keys as other, and values for each key are the same in self and other.
Returns true if this tuple has the same keys as other, and values for each key are the same in self and other.
Returns the value for the given key if there is such a key, otherwise raises KeyError.
Returns the value for the given key if there is such a key, otherwise returns nil.
Returns a named tuple with the same keys but with cloned values, using the #clone method.
Traverses the depth of a structure and returns the value, otherwise raises KeyError.
Traverses the depth of a structure and returns the value.
Yields each key and value in this named tuple.
Yields each key in this named tuple.
Yields each value in this named tuple.
Yields each key and value, together with an index starting at offset, in this named tuple.
Returns true if this named tuple is empty.
Returns the value for the given key, if there's such key, otherwise returns default_value.
Returns the value for the given key, if there's such key, otherwise the value returned by the block.
Returns the value for the given key, if there's such key, otherwise the value returned by the block.
Expects to be called on a named tuple whose values are types, creates a tuple from the given hash, with types casted appropriately.
Returns true if this named tuple has the given key, false otherwise.
Returns true if this named tuple has the given key, false otherwise.
Returns a hash value based on this name tuple's size, keys and values.
Same as #to_s.
Returns a Tuple of symbols with the keys in this named tuple.
Returns an Array populated with the results of each iteration in the given block, which is given each key and value in this named tuple.
Merges two named tuples into one, returning a new named tuple.
Merges two named tuples into one, returning a new named tuple.
Merges two named tuples into one, returning a new named tuple.
Merges two named tuples into one, returning a new named tuple.
Returns the number of elements in this named tuple.
Returns a Tuple of symbols with the keys in this named tuple, sorted by name.
Returns a new Array of tuples populated with each key-value pair.
Returns an Array with the results of running block against tuples with key and values belonging to this NamedTuple.
Returns a Hash with the keys and values in this named tuple.
Appends a string representation of this named tuple to the given IO.
Returns a Tuple with the values in this named tuple.
Value
Object
Object
Object
Creates a named tuple from the given hash, with elements casted to the given types. Here the Int32 | String union is cast to Int32.
num_or_str = 42.as(Int32 | String)
NamedTuple(name: String, val: Int32).from({"name" => "number", "val" => num_or_str}) # => {name: "number", val: 42}
num_or_str = "a string".as(Int32 | String)
NamedTuple(name: String, val: Int32).from({"name" => "number", "val" => num_or_str}) # raises TypeCastError (Cast from String to Int32 failed) See also: #from.
Creates a named tuple that will contain the given arguments.
With a named tuple literal you cannot create an empty named tuple. This method doesn't have this limitation, which makes it especially useful in macros and generic code.
NamedTuple.new(name: "Crystal", year: 2011) #=> {name: "Crystal", year: 2011}
NamedTuple.new # => {}
{} # syntax error Returns the value type for the given key if there is such a key, otherwise raises KeyError. Read the type docs to understand the difference between indexing with a literal or a variable.
alias Foo = NamedTuple(name: String, year: Int32) Foo[:name] # => String Foo["year"] # => Int32 Foo["year"].zero # => 0 Foo[:other] # => Error: missing key 'other' for named tuple NamedTuple(name: String, year: Int32).class key = :year Foo[key] # => Int32 Foo[key].zero # Error: undefined method 'zero' for String.class (compile-time type is (Int32.class | String.class)) key = "other" Foo[key] # raises KeyError
Returns the value type for the given key if there is such a key, otherwise returns nil. Read the type docs to understand the difference between indexing with a literal or a variable.
alias Foo = NamedTuple(name: String, year: Int32) Foo[:name]? # => String Foo["year"]? # => Int32 Foo["year"]?.zero # => 0 Foo[:other]? # => nil typeof(Foo[:other]?) # => Nil key = :year Foo[key]? # => Int32 Foo[key]?.zero # Error: undefined method 'zero' for String.class (compile-time type is (Int32.class | String.class | Nil)) key = "other" Foo[key]? # => nil
Returns the types of this named tuple type.
tuple = {a: 1, b: "hello", c: 'x'}
tuple.class.types # => {a: Int32, b: String, c: Char} Returns true if this tuple has the same keys as other, and values for each key are the same in self and other.
tuple1 = {name: "Crystal", year: 2011}
tuple2 = {year: 2011, name: "Crystal"}
tuple3 = {name: "Crystal", year: 2012}
tuple4 = {name: "Crystal", year: 2011.0}
tuple1 == tuple2 # => true
tuple1 == tuple3 # => false
tuple1 == tuple4 # => true Returns true if this tuple has the same keys as other, and values for each key are the same in self and other.
tuple1 = {name: "Crystal", year: 2011}
tuple2 = {year: 2011, name: "Crystal"}
tuple3 = {name: "Crystal", year: 2012}
tuple4 = {name: "Crystal", year: 2011.0}
tuple1 == tuple2 # => true
tuple1 == tuple3 # => false
tuple1 == tuple4 # => true Returns the value for the given key if there is such a key, otherwise raises KeyError. Read the type docs to understand the difference between indexing with a literal or a variable.
tuple = {name: "Crystal", year: 2011}
tuple[:name] # => "Crystal"
typeof(tuple[:name]) # => String
tuple["year"] # => 2011
typeof(tuple["year"]) # => Int32
tuple[:other] # Error: missing key 'other' for named tuple NamedTuple(name: String, year: Int32)
key = :name
tuple[key] # => "Crystal"
typeof(tuple[key]) # => (Int32 | String)
key = "year"
tuple[key] # => 2011
key = :other
tuple[key] # raises KeyError Returns the value for the given key if there is such a key, otherwise returns nil. Read the type docs to understand the difference between indexing with a literal or a variable.
tuple = {name: "Crystal", year: 2011}
tuple[:name]? # => "Crystal"
typeof(tuple[:name]?) # => String
tuple["year"]? # => 2011
typeof(tuple["year"]?) # => Int32
tuple[:other]? # => nil
typeof(tuple[:other]?) # => Nil
key = :name
tuple[key]? # => "Crystal"
typeof(tuple[key]?) # => (Int32 | String | Nil)
key = "year"
tuple[key]? # => 2011
key = :other
tuple[key]? # => nil Returns a named tuple with the same keys but with cloned values, using the #clone method.
Traverses the depth of a structure and returns the value, otherwise raises KeyError.
h = {a: {b: {c: [10, 20]}}, x: {a: "b"}}
h.dig :a, :b, :c # => [10, 20]
h.dig "a", "x" # raises KeyError Traverses the depth of a structure and returns the value. Returns nil if not found.
h = {a: {b: {c: [10, 20]}}, x: {a: "b"}}
h.dig? :a, :b, :c # => [10, 20]
h.dig? "a", "x" # => nil Yields each key and value in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.each do |key, value|
puts "#{key} = #{value}"
end Output:
name = Crystal year = 2011
Yields each key in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.each_key do |key|
puts key
end Output:
name year
Yields each value in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.each_value do |value|
puts value
end Output:
Crystal 2011
Yields each key and value, together with an index starting at offset, in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.each_with_index do |key, value, i|
puts "#{i + 1}) #{key} = #{value}"
end Output:
1) name = Crystal 2) year = 2011
Returns true if this named tuple is empty.
tuple = {name: "Crystal", year: 2011}
tuple.empty? # => false Returns the value for the given key, if there's such key, otherwise returns default_value.
tuple = {name: "Crystal", year: 2011}
tuple.fetch(:name, "Unknown") # => "Crystal"
tuple.fetch("year", 0) # => 2011
tuple.fetch(:other, 0) # => 0 Returns the value for the given key, if there's such key, otherwise the value returned by the block.
tuple = {name: "Crystal", year: 2011}
tuple.fetch(:name) { "Unknown" } # => "Crystal"
tuple.fetch(:other) { 0 } # => 0 Returns the value for the given key, if there's such key, otherwise the value returned by the block.
tuple = {name: "Crystal", year: 2011}
tuple.fetch("name") { "Unknown" } # => "Crystal"
tuple.fetch("other") { 0 } # => 0 Expects to be called on a named tuple whose values are types, creates a tuple from the given hash, with types casted appropriately. The hash keys must be either symbols or strings.
This allows you to easily pass a hash as individual named arguments to a method.
require "json"
def speak_about(thing : String, n : Int64)
"I see #{n} #{thing}s"
end
hash = JSON.parse(%({"thing": "world", "n": 2})).as_h # hash : Hash(String, JSON::Any)
hash = hash.transform_values(&.raw) # hash : Hash(String, JSON::Any::Type)
speak_about(**{thing: String, n: Int64}.from(hash)) # => "I see 2 worlds" Returns true if this named tuple has the given key, false otherwise.
tuple = {name: "Crystal", year: 2011}
tuple.has_key?(:name) # => true
tuple.has_key?(:other) # => false Returns true if this named tuple has the given key, false otherwise.
tuple = {name: "Crystal", year: 2011}
tuple.has_key?(:name) # => true
tuple.has_key?(:other) # => false Returns a hash value based on this name tuple's size, keys and values.
See also: Object#hash. See Object#hash(hasher)
Returns a Tuple of symbols with the keys in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.keys # => {:name, :year} Returns an Array populated with the results of each iteration in the given block, which is given each key and value in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.map { |k, v| "#{k}: #{v}" } # => ["name: Crystal", "year: 2011"] Merges two named tuples into one, returning a new named tuple. If a key is defined in both tuples, the value and its type is used from other.
a = {foo: "Hello", bar: "Old"}
b = {bar: "New", baz: "Bye"}
a.merge(b) # => {foo: "Hello", bar: "New", baz: "Bye"} Merges two named tuples into one, returning a new named tuple. If a key is defined in both tuples, the value and its type is used from other.
a = {foo: "Hello", bar: "Old"}
b = {bar: "New", baz: "Bye"}
a.merge(b) # => {foo: "Hello", bar: "New", baz: "Bye"} Merges two named tuples into one, returning a new named tuple. If a key is defined in both tuples, the value and its type are used from self (original tuple)
a = {foo: "Hello", bar: "Old"}
b = {bar: "New", baz: "Bye"}
a.reverse_merge(b) # => {foo: "Hello", bar: "Old", baz: "Bye"} Merges two named tuples into one, returning a new named tuple. If a key is defined in both tuples, the value and its type are used from self (original tuple)
a = {foo: "Hello", bar: "Old"}
b = {bar: "New", baz: "Bye"}
a.reverse_merge(b) # => {foo: "Hello", bar: "Old", baz: "Bye"} Returns the number of elements in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.size # => 2 Returns a Tuple of symbols with the keys in this named tuple, sorted by name.
tuple = {foo: 1, bar: 2, baz: 3}
tuple.sorted_keys # => {:bar, :baz, :foo} Appends a string representation of this named tuple to the given IO.
tuple = {name: "Crystal", year: 2011}
tuple.to_s # => %({name: "Crystal", year: 2011}) Returns a Tuple with the values in this named tuple.
tuple = {name: "Crystal", year: 2011}
tuple.values # => {"Crystal", 2011}
© 2012–2026 Manas Technology Solutions.
Licensed under the Apache License, Version 2.0.
https://crystal-lang.org/api/1.19.0/NamedTuple.html