Open, read and write binary into a file

I think it’s completely clear ! A pleasure to see you by camera, definitely better !

1 Like

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"]}

Run it

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.

1 Like