<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sam</title>
    <description>The latest articles on DEV Community by Sam (@samyeyo).</description>
    <link>https://dev.to/samyeyo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F583447%2F25958a9f-2861-44e9-85cb-c079f833e987.png</url>
      <title>DEV Community: Sam</title>
      <link>https://dev.to/samyeyo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samyeyo"/>
    <language>en</language>
    <item>
      <title>Compile lua scripts to exe</title>
      <dc:creator>Sam</dc:creator>
      <pubDate>Sat, 04 Feb 2023 11:33:14 +0000</pubDate>
      <link>https://dev.to/samyeyo/compile-lua-scripts-to-exe-3mpc</link>
      <guid>https://dev.to/samyeyo/compile-lua-scripts-to-exe-3mpc</guid>
      <description>&lt;p&gt;Have you ever wanted to compile your Lua scripts into Windows executables? Having trouble deploying Lua programs on other computers? Here's a quick and easy way to turn your Lua scripts into executables.&lt;/p&gt;

&lt;h2&gt;
  
  
  rtc, an open source Lua to exe compiler
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;rtc&lt;/strong&gt; is a simple command line tool to build standalone executables from your Lua scripts. A GUI front end is available for those who are resistant to the console.&lt;br&gt;
&lt;strong&gt;rtc&lt;/strong&gt; can be downloaded on the &lt;a href="https://github.com/samyeyo/rtc"&gt;GitHub project homepage&lt;/a&gt;, and available for x86 and x64 Windows platforms.&lt;br&gt;
Once downloaded, put the content of the ZIP archive on your hard disk and make sure it's available on your system PATH.&lt;/p&gt;
&lt;h2&gt;
  
  
  Let's build our first executable
&lt;/h2&gt;

&lt;p&gt;Create a simple &lt;code&gt;hello.lua&lt;/code&gt; file containing this script :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello World !"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;io.stdin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"*l"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, open a console or terminal prompt, go to the folder where you have saved the file &lt;code&gt;hello.lua&lt;/code&gt; and enter the following command :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rtc hello.lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And voila ! &lt;code&gt;rtc&lt;/code&gt; should have produced an executable named &lt;code&gt;hello.exe&lt;/code&gt;. You can run it like any other executable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static executables with rtc
&lt;/h2&gt;

&lt;p&gt;By default, &lt;code&gt;rtc&lt;/code&gt; creates dynamic executables, meaning the Lua VM is in the library &lt;code&gt;lua54.dll&lt;/code&gt; and its needed to run any program built with &lt;code&gt;rtc&lt;/code&gt; (this dependency can be found along your executable or in your system PATH).&lt;/p&gt;

&lt;p&gt;If you want to get rid of this library dependency, you can tell &lt;code&gt;rtc&lt;/code&gt; to build a static executable with the &lt;code&gt;-s&lt;/code&gt; option :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rtc &lt;span class="nt"&gt;-s&lt;/span&gt; hello.lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;hello.exe&lt;/code&gt; file will be fatter, as it includes now the Lua VM. But be careful with those static executables, as it is strongly discouraged to require for Lua binary modules (may lead to crash). Use this option only if your program don't need any Lua binary module.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next ?
&lt;/h2&gt;

&lt;p&gt;This tutorial shows basic usage of &lt;code&gt;rtc&lt;/code&gt;. But there is more functionnalities available, like generating Desktop executables, changing default executable icon, embedding content...&lt;/p&gt;

&lt;p&gt;Please read the &lt;a href="https://luart.org/doc/toolchain/rtc.html"&gt;rtc documentation&lt;/a&gt; for more on this.&lt;/p&gt;

</description>
      <category>windows</category>
      <category>lua</category>
      <category>exe</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Working with ZIP files in LuaRT</title>
      <dc:creator>Sam</dc:creator>
      <pubDate>Tue, 28 Sep 2021 17:09:06 +0000</pubDate>
      <link>https://dev.to/samyeyo/working-with-zip-files-in-luart-2lm0</link>
      <guid>https://dev.to/samyeyo/working-with-zip-files-in-luart-2lm0</guid>
      <description>&lt;p&gt;&lt;a href="https://www.luart.org"&gt;LuaRT&lt;/a&gt; provides a builtin &lt;code&gt;compression&lt;/code&gt; module to work with compressed files in ZIP format, without any additional dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  ZIP archive files
&lt;/h2&gt;

&lt;p&gt;ZIP is a file format that supports lossless compression. A lossless compression algorithm allows the original data to be perfectly reconstructed from the compressed data. A ZIP file contains one or more compressed files, making it an ideal way to reduce the size of large files and keep related files together.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Zip Object
&lt;/h2&gt;

&lt;p&gt;The LuaRT &lt;code&gt;compression&lt;/code&gt; module provides an abstraction of zip files represented as a &lt;code&gt;Zip&lt;/code&gt; Object. Only INFLATE/DEFLATE algorithms are supported.&lt;br&gt;
This Object facilitates the creation of ZIP archive files and provides methods and properties for adding and extracting compressed files.&lt;/p&gt;

&lt;p&gt;To use the &lt;code&gt;Zip&lt;/code&gt; Object, you must first require for the &lt;code&gt;compression&lt;/code&gt; module :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- require the builtin 'compression' module&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;compression&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"compression"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extract files from a ZIP archive
&lt;/h2&gt;

&lt;p&gt;To extract files from an existing ZIP archive, you can use the &lt;code&gt;Zip:extractall()&lt;/code&gt; method :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;compression&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"compression"&lt;/span&gt;

&lt;span class="c1"&gt;-- Create a Zip instance to represent the ZIP file 'archive.zip'&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;archive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;compression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"archive.zip"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- open the ZIP archive for reading&lt;/span&gt;
&lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- extract and uncompress all the files in the current directory&lt;/span&gt;
&lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;extractall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can extract a specific entry with the &lt;code&gt;Zip:extract()&lt;/code&gt; method :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- extract the ZIP entry "extractme.bin" in the current directory &lt;/span&gt;
&lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"extractme.bin"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A destination path can optionaly be provided :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- extract the ZIP entry "data.bin" in the specified directory &lt;/span&gt;
&lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"data.bin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"C:\\Extract\\Me\\Here"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a ZIP archive
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Zip:open()&lt;/code&gt; can be used to create an empty ZIP archive. Files can be added to the archive with the &lt;code&gt;Zip:write()&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;compression&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"compression"&lt;/span&gt;

&lt;span class="c1"&gt;-- Create a Zip value to represent the ZIP file 'new.zip'&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;archive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;compression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"new.zip"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- open the ZIP archive for writing&lt;/span&gt;
&lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"write"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- add a file to this archive&lt;/span&gt;
&lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"C:\\addme.txt"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can recursively add entire directories too :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"C:\\I_am_a_directory_addme\\"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Iterating over files in a ZIP archive
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Zip&lt;/code&gt; object is iterable with the &lt;code&gt;each()&lt;/code&gt; function, returning at every iteration the next entry name in the ZIP archive previously opened in "read" mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;compmression&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"compression"&lt;/span&gt;

&lt;span class="c1"&gt;-- Create a Zip value to represent the ZIP file 'archive.zip'&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;compression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"archive.zip"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- open the ZIP archive for reading&lt;/span&gt;
&lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- Iterate over each ZIP archive entries and extract it&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
   &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Extracting '"&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="s2"&gt;"'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reading ZIP archive entries in memory
&lt;/h2&gt;

&lt;p&gt;ZIP archive entries can also be extracted in-memory using the &lt;code&gt;Zip:read()&lt;/code&gt; method :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;compression&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"compression"&lt;/span&gt;

&lt;span class="c1"&gt;-- Create a Zip value to represent the ZIP file 'archive.zip'&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;archive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;compression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"archive.zip"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- open the ZIP archive for reading&lt;/span&gt;
&lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- print the content of the ZIP archive entry 'README.TXT'&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"README.TXT"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, LuaRT's &lt;code&gt;compression&lt;/code&gt; module provides an easy way to manage ZIP archives. Additionally, you can read the complete &lt;a href="https://www.luart.org/doc/compression/index.html"&gt;compression module&lt;/a&gt; module documentation.&lt;/p&gt;

</description>
      <category>lua</category>
      <category>windows</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Using files in LuaRT</title>
      <dc:creator>Sam</dc:creator>
      <pubDate>Thu, 27 May 2021 06:52:57 +0000</pubDate>
      <link>https://dev.to/samyeyo/using-files-in-luart-34b9</link>
      <guid>https://dev.to/samyeyo/using-files-in-luart-34b9</guid>
      <description>&lt;p&gt;&lt;a href="https://www.luart.org"&gt;LuaRT&lt;/a&gt; is a comprehensive Windows framework to develop in Lua with a specific runtime library. In the Lua standard library, input / output functionalities are gathered within the io module. In LuaRT, they are grouped together within the &lt;a href="https://www.luart.org/doc/sys/index.html"&gt;sys&lt;/a&gt; module, and more particularly the &lt;a href="https://www.luart.org/doc/sys/file.html"&gt;File&lt;/a&gt; object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the File object in LuaRT
&lt;/h2&gt;

&lt;p&gt;The manipulation of files in LuaRT is facilitated by the use of &lt;strong&gt;File&lt;/strong&gt; objects: creation of files, opening, closing, moving, copying, deleting ...&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating a File value
&lt;/h4&gt;

&lt;p&gt;At this point, it's important to understand that a &lt;strong&gt;File&lt;/strong&gt; object represents an abstraction of a file that may &lt;em&gt;or may not&lt;/em&gt; physically exist. For example, when creating a new file, only the call to the &lt;strong&gt;File:open()&lt;/strong&gt; method will physically create the file on the computer's storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;newfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hello.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- newfile holds a File value&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- outputs false&lt;/span&gt;
&lt;span class="n"&gt;newfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"write"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- creates the file physically on the disk &lt;/span&gt;
&lt;span class="n"&gt;newfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;       &lt;span class="c1"&gt;-- closes the opened File&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- now outputs true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  File operations
&lt;/h4&gt;

&lt;p&gt;A &lt;strong&gt;File&lt;/strong&gt; object can be used to perform file operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"test.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"test_copy.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;-- copies file&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"C:\"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;             &lt;span class="c1"&gt;-- moves file&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                &lt;span class="c1"&gt;-- deletes the file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Opening and closing a File
&lt;/h4&gt;

&lt;p&gt;A file can be opened to read or write its content. This is done by calling the &lt;strong&gt;File:open()&lt;/strong&gt; method. By default, the file is open in "read" mode. The file encoding can be specified as a second argument or detected using Byte Mark Order :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"test.bin"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   &lt;span class="c1"&gt;-- opens the file "test.bin" in read mode (encoding is autodetected)&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                   &lt;span class="c1"&gt;-- closes the file&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"write"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"binary"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;-- open the file in write mode (erasing its previous content), using "binary" encoding(ie raw binary)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Do not forget to close a file after the transaction on this one ended. This is done automatically when the &lt;strong&gt;File&lt;/strong&gt; object is garbage collected, but that cannot be predicted.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Reading and writing Files
&lt;/h4&gt;

&lt;p&gt;Once the &lt;strong&gt;File&lt;/strong&gt; object has been created, and the &lt;strong&gt;File:open()&lt;/strong&gt; method called, you can write or read on the &lt;strong&gt;File&lt;/strong&gt; (depending on the mode used in the call). These methods return Buffer objects in binary mode (containing in memory binary data) or strings in UTF8 or UNICODE mode.&lt;/p&gt;

&lt;h5&gt;
  
  
  Reading file content
&lt;/h5&gt;

&lt;p&gt;There are two methods for reading the content of a file: &lt;strong&gt;File:read()&lt;/strong&gt; and &lt;strong&gt;File:readln()&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"README.TXT"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;-- opens the File for reading&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;  &lt;span class="c1"&gt;-- reads and prints all the file content &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;File:read()&lt;/strong&gt; method reads a number of characters (when using UTF8 or UNICODE mode) or bytes (in binary mode) specified as argument, or all the content of the file if no argument is provided.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;File:readln()&lt;/strong&gt; method reads a line (until end of line characters "\r\n" or "\n" are encountered).&lt;/p&gt;

&lt;h5&gt;
  
  
  Writing to files
&lt;/h5&gt;

&lt;p&gt;There are two methods for writing data to a file: &lt;strong&gt;File:write()&lt;/strong&gt; and &lt;strong&gt;File:writeln()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each method take one argument, converted to a string to be written to the file. In binary mode, &lt;strong&gt;Buffer&lt;/strong&gt; objects can be used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File:writeln()&lt;/strong&gt; writes a line to the file, appending "\r\n" (corresponding to the End Of Line marker on Windows).&lt;/p&gt;

&lt;h4&gt;
  
  
  File position
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;File.position&lt;/strong&gt; property get or set the current file position, as a number. File position always starts at 1 (as for all indexed/positioned values in Lua). &lt;br&gt;
File position interpretation depends on the file encoding.&lt;br&gt;
In "binary" encoding : the position is expressed in bytes.&lt;br&gt;
In "utf8" or "unicode" encoding : the position is expressed in characters.&lt;br&gt;
The &lt;strong&gt;File.eof&lt;/strong&gt; property checks if the end of the file have been reached.&lt;/p&gt;

&lt;h4&gt;
  
  
  File timestamps
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;File.accessed&lt;/strong&gt;, &lt;strong&gt;File.modified&lt;/strong&gt; and &lt;strong&gt;File.created&lt;/strong&gt; permits to set or get timestamps using a &lt;strong&gt;Datetime&lt;/strong&gt; object (in LuaRT, &lt;strong&gt;Datetime&lt;/strong&gt; objects represent a moment, a combination of a date and a time).&lt;/p&gt;

&lt;h4&gt;
  
  
  File attributes
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;File.hidden&lt;/strong&gt;, &lt;strong&gt;File.temporary&lt;/strong&gt; and &lt;strong&gt;File.readonly&lt;/strong&gt; permits to set or get the corresponding attributes.&lt;/p&gt;

&lt;h4&gt;
  
  
  File path and names
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;File.fullpath&lt;/strong&gt;, &lt;strong&gt;File.filename&lt;/strong&gt;, &lt;strong&gt;File.extension&lt;/strong&gt;, &lt;strong&gt;File.path&lt;/strong&gt; permits to get access to the different parts of a filename.&lt;/p&gt;

&lt;p&gt;As you can see, File objects provide easy access to all of the functionality related to creating, reading, writing and manipulating files in LuaRT. These features go beyond the capabilities offered by the standard Lua library. &lt;/p&gt;

</description>
      <category>lua</category>
      <category>windows</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Lua strings are not strings</title>
      <dc:creator>Sam</dc:creator>
      <pubDate>Sun, 21 Feb 2021 16:36:37 +0000</pubDate>
      <link>https://dev.to/samyeyo/lua-strings-are-not-strings-6f4</link>
      <guid>https://dev.to/samyeyo/lua-strings-are-not-strings-6f4</guid>
      <description>&lt;p&gt;Yes, you read that right. It could have been worthy of a shakespear play but when it comes to strings in Lua, it can turn into a nightmare if you don't pay attention with the true definition of what a string is...&lt;/p&gt;

&lt;h4&gt;
  
  
  "Wait, what do you mean by strings are not strings?"
&lt;/h4&gt;

&lt;p&gt;In Lua, strings could have been called buffers, arrays, or even containers. Indeed strings are only &lt;em&gt;containers&lt;/em&gt;. But it does not contain characters. In fact, Lua has no idea what a character is.&lt;/p&gt;

&lt;h4&gt;
  
  
  "So what a string contains ?"
&lt;/h4&gt;

&lt;p&gt;You may then wonder what the strings contain: they simply contain &lt;strong&gt;bytes&lt;/strong&gt;. Strings can therefore, in Lua, contain lots of things: an image, a digitized sound, a database ... and characters too.&lt;/p&gt;

&lt;p&gt;This is where things get complicated: Lua considers that in strings, a single byte corresponds to a single character. This is fine as long as you are using single-byte encoded characters (as with ASCII encoding), with only 255 character possibilities.&lt;/p&gt;

&lt;p&gt;But in the age of the Internet, when the whole world communicates in all languages, that seems rather restrictive ! Fortunately other encodings than ASCII exist, to extend the number of usable characters: UTF8, UCS 2 LE, UCS 2 BE,...&lt;br&gt;
They allow to encode a character over several bytes.&lt;/p&gt;
&lt;h4&gt;
  
  
  Multibytes characters
&lt;/h4&gt;

&lt;p&gt;Multibytes characters can be stored in Lua strings after all, as strings in Lua contains bytes.&lt;br&gt;
Yes, that's right. But it does not mean you can &lt;em&gt;use&lt;/em&gt; them !&lt;/p&gt;
&lt;h4&gt;
  
  
  One rule to rule them all
&lt;/h4&gt;

&lt;p&gt;All Lua strings functionnalities (concatenation, length calculation, string.find, string.gmatch, string.sub...) consider that strings contain only single byte characters : the same rule again !&lt;/p&gt;

&lt;p&gt;Here is an example that illustrates the problem (the script must have been saved with UTF8 encoding +/- BOM)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;summer_infrench&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"été"&lt;/span&gt;

&lt;span class="c1"&gt;-- outputs 5 !?&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;string.len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summer_infrench&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;-- pos = 3 !?&lt;/span&gt;
&lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;string.find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summer_infrench&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"t"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  What's going on ?
&lt;/h4&gt;

&lt;p&gt;Remember the rule : strings are considered as bytes containers. The UTF8 string "été" (means 'summer' in French) is 3 characters long, but occupies 5 bytes in memory :&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;é&lt;/th&gt;
&lt;th&gt;t&lt;/th&gt;
&lt;th&gt;é&lt;/th&gt;
&lt;th&gt;= 3 characters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0xC3 0xA9&lt;/td&gt;
&lt;td&gt;0x75&lt;/td&gt;
&lt;td&gt;0xC3 0xA9&lt;/td&gt;
&lt;td&gt;= 5 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That's why the function &lt;em&gt;string.len&lt;/em&gt; returns 5 and not 3.&lt;br&gt;
The same for &lt;em&gt;string.find&lt;/em&gt; : The byte position of the "t" character is 3.&lt;/p&gt;
&lt;h4&gt;
  
  
  Is there any workaround ?
&lt;/h4&gt;

&lt;p&gt;Hopefully, yes there is one. Since Lua 5.3 a new module "utf8" is available to help developers with UTF8 encoded strings. But this greatly complicates the use of UTF8 strings, as it uses specific functions. A kind of overlay over strings. Not very friendly : in other modern programming languages, strings are containers for characters and support natively multibytes encodings.&lt;/p&gt;

&lt;p&gt;Here is the previous example using the "utf8" module :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;utf8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"utf8"&lt;/span&gt;

&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;summer_infrench&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"été"&lt;/span&gt;

&lt;span class="c1"&gt;-- yes ! outputs 3 !&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;utf8.len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summer_infrench&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;-- Still pos = 3, no solution for string.find with UTF8 strings&lt;/span&gt;
&lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;string.find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summer_infrench&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"t"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  What if I want to use UTF8 strings with Lua ?
&lt;/h4&gt;

&lt;p&gt;It's in Lua philosophy : if Lua lacks something, implement it using binary modules or Lua modules. Search on the net and you will find some of them. But again, for such a simple functionality, this represents a certain degree of complication especially for beginners. &lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;I hope this article has helped to better understand the use of strings in Lua. This is also the main reason why I decided to natively implement UTF8 strings in my LuaRT project.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>lua</category>
    </item>
  </channel>
</rss>
