Programming Crystal by Ivo Balbaert & Simon St. Laurent

Programming Crystal by Ivo Balbaert & Simon St. Laurent

Author:Ivo Balbaert & Simon St. Laurent [Balbaert, Ivo]
Language: eng
Format: azw3
Tags: Pragmatic Bookshelf
Publisher: Pragmatic Bookshelf
Published: 2019-01-30T00:00:00+00:00


Structuring a Class

In the previous section, and in ​Organizing Code in Classes and Modules​, you saw a simple Mineral class. Here’s the class code by itself without any additional logic:

​ ​class​ Mineral

​ getter name : String

​ getter hardness : Float64

​ getter crystal_struct : String

​

​ ​def​ ​initialize​(@name, @hardness, @crystal_struct) ​# constructor​

​ ​end​

​ ​end​

This class has three read-only instance variables: name, hardness, and crystal_struct. Giving them a type is imposed by the Crystal compiler. But you can also do this in the initialize method:

classes_and_structs/classes.cr

​ ​class​ Mineral

​ getter name, hardness, crystal_struct

​

​ ​def​ ​initialize​(@name : String,

​ @hardness : Float64,

​ @crystal_struct : String)

​ ​end​

​ ​end​

Default values can be assigned like this:

​ ​def​ ​initialize​(@name : String = ​"unknown"​, ...)

​ ​end​

Some people use symbols like :hardness for the property name, but it isn’t required. A property without a type must have a default value. Or you could give it a value in initialize (try it!). You don’t need to define variables at the start of the class.

The new method creates a Mineral object:

​ min1 = Mineral.​new​(​"gold"​, 1.0, ​"cubic"​)

​ min1 ​# => #<Mineral:0x271cf00 @crystal_struct="cubic",​

​ ​# => @hardness=1.0, @name="gold">​

​ min1.​object_id​ ​# => 41012992 == 0x271cf00​

​ typeof(min1) ​# => Mineral # compile-time type​

​ min1.​class​ ​# => Mineral # run-time type​

​ Mineral.​class​ ​# => Class # all classes have type Class​

new is a class method that’s created automatically for every class. It allocates memory, calls initialize, and then returns the newly created object. An object is created on the heap and it has an object_id: its memory address. When it gets a new name or when it’s passed to a method, only the reference is passed. This means the object is changed when it’s changed in the method.

When you’re not sure which types your initialize method will accept, you can also use generic types like T, as in this class Mineralg:

classes_and_structs/classes.cr

​ ​class​ Mineralg(T)

​ getter name

​

​ ​def​ ​initialize​(@name : T)

​ ​end​

​ ​end​

​

​ min = Mineralg.​new​(​"gold"​)

​ min2 = Mineralg.​new​(42)

​ min3 = Mineralg(String).​new​(42)

​

​ ​# => Error: no overload matches 'Mineralg(String).new' with type Int32​

When naming instance variables, prefix them with @. For class variables, use @@, like the @@planet our mineral species comes from. All objects built using this class will share this variable, and its value will be the same to all of them. (However, subclasses, which you’ll see in the next section, all get their own copy with the value shared across the subclass.)

To name properties that can change, such as quantity in the code that follows, prefix them with property. For write-only properties that can’t be read, use the prefix setter, like id in the following code. Trying to show them is an error:

classes_and_structs/classes.cr

​ ​class​ Mineral

​ @@planet = ​"Earth"​

​

​ getter name, hardness, crystal_struct

​ setter id

​ property quantity : Float32

​

​ ​def​ ​initialize​(@id : Int32, @name : String, @hardness : Float64,

​ @crystal_struct : String)

​ @quantity = 0f32

​ ​end​

​

​ ​def​ self.​planet​

​ @@planet

​ ​end​

​ ​end​

​

​ min1 = Mineral.​new​(101, ​"gold"​, 1.0, ​"cubic"​)

​ min1.​quantity​ = 453.0f32 ​# => 453.0​

​ min1.​id​ ​# => Error: undefined method 'id' for Mineral​

​ Mineral.​planet​ ​# => "Earth"​

​

​ min2 = min1.​dup​

​ min1 == min2



Download



Copyright Disclaimer:
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.