I think it’s completely clear ! A pleasure to see you by camera, definitely better !
I have an another question now. If I would like to do the opposite ? If I would like to export a class to a json file, how I can do that ? With wich method ? to_json method ?
For example, this is one of my implementation with json. I’m already able to import json data file.
How can I export a SoftwareInformation data to json file ?
module ISM
class SoftwareInformation
record Option,
name : String,
description : String,
active : Bool do
include JSON::Serializable
end
record Dependency,
name : String,
version : String,
options : Array(Option) do
include JSON::Serializable
end
record Information,
name : String,
version : String,
architectures : Array(String),
description : String,
website : String,
downloadLinks : Array(String),
signatureLinks : Array(String),
shasumLinks : Array(String),
dependencies : Array(Dependency),
options : Array(Option) do
include JSON::Serializable
end
property name = ISM::Default::SoftwareInformation::Name
property version = ISM::Default::SoftwareInformation::Version
property architectures = ISM::Default::SoftwareInformation::Architectures
property description = ISM::Default::SoftwareInformation::Description
property website = ISM::Default::SoftwareInformation::Website
property downloadLinks = ISM::Default::SoftwareInformation::DownloadLinks
property signatureLinks = ISM::Default::SoftwareInformation::SignatureLinks
property shasumLinks = ISM::Default::SoftwareInformation::ShasumLinks
property dependencies = ISM::Default::SoftwareInformation::Dependencies
property options = ISM::Default::SoftwareInformation::Options
def initialize( name = ISM::Default::SoftwareInformation::Name,
version = ISM::Default::SoftwareInformation::Version,
architectures = ISM::Default::SoftwareInformation::Architectures,
description = ISM::Default::SoftwareInformation::Description,
website = ISM::Default::SoftwareInformation::Website,
downloadLinks = ISM::Default::SoftwareInformation::DownloadLinks,
signatureLinks = ISM::Default::SoftwareInformation::SignatureLinks,
shasumLinks = ISM::Default::SoftwareInformation::ShasumLinks,
dependencies = ISM::Default::SoftwareInformation::Dependencies,
options = ISM::Default::SoftwareInformation::Options)
@name = name
@version = version
@architectures = architectures
@description = description
@website = website
@downloadLinks = downloadLinks
@signatureLinks = signatureLinks
@shasumLinks = shasumLinks
@dependencies = dependencies
@options = options
end
def loadInformationFile(informationFilePath = ISM::Default::Software::InformationFilePath)
information = Information.from_json(File.read(informationFilePath))
@name = information.name
@version = information.version
@architectures = information.architectures
@description = information.description
@website = information.website
@downloadLinks = information.downloadLinks
@signatureLinks = information.signatureLinks
@shasumLinks = information.shasumLinks
information.dependencies.each do |data|
dependency = ISM::SoftwareDependency.new
dependency.name = data.name
dependency.version = data.version
data.options.each do |entry|
option = ISM::SoftwareOption.new
option.name = entry.name
option.description = entry.description
option.active = entry.active
dependency.options.push(option)
end
@dependencies.push(dependency)
end
information.options.each do |data|
option = ISM::SoftwareOption.new
option.name = data.name
option.description = data.description
@options.push(option)
end
end
def versionName
return @name+"-"+@version
end
end
end
I think I found a part of the solution:
(it’s an example)
record Information,
name : String,
version : String,
architectures : Array(String) do
include JSON::Serializable
end
sft = Information.new("Binutils","2.37",["x86_64","arm"])
puts sft.name
sft.to_json(File.open("Test.json","w"))
But can I provide a default value of my record properties ? Because I would like for example to setup an empty record, and after for example do :
sft = Information.new
sft.name = "Something"
The default value is easy:
record Information,
name : String = "DefaultName",
version : String = "0.0.1",
architectures : Array(String) = ["x86_64"] do
include JSON::Serializable
end
However, modifying it is more complicated. The record
macro is designed for creating immutable Structs (i.e. you can’t change them after they’re created). You could instead just use a standard Struct
definition:
require "json"
struct Information
include JSON::Serializable
property name : String = "DefaultName"
property version : String = "0.0.1"
property architectures : Array(String) = ["x86_64"]
def initialize
end
def initialize(@name, @version, @architectures)
end
end
sft = Information.new("Binutils","2.37",["x86_64","arm"])
puts sft.name # => Binutils
puts sft.to_json # => {"name":"Binutils","version":"2.37","architectures":["x86_64","arm"]}
default = Information.new
puts default.to_json # => {"name":"DefaultName","version":"0.0.1","architectures":["x86_64"]}
non_default = default.dup
non_default.name = "NonDefault"
puts non_default.to_json # => {"name":"NonDefault","version":"0.0.1","architectures":["x86_64"]}
As always when using Structs, you need to remember that they’re passed by value: docs.
This is precisely the reason the record
macro makes objects immutable. :-D If your objects accumulate their own state outside of initialize
, it’s almost always a good idea to use class
instead. It’s too easy to get confused when changed state of a struct doesn’t stick.