<?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: Ali Al Khawaja</title>
    <description>The latest articles on DEV Community by Ali Al Khawaja (@ali-alkhawaja).</description>
    <link>https://dev.to/ali-alkhawaja</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%2F1941915%2F6524dfe6-2720-474e-a55e-32e8d370439b.png</url>
      <title>DEV Community: Ali Al Khawaja</title>
      <link>https://dev.to/ali-alkhawaja</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ali-alkhawaja"/>
    <language>en</language>
    <item>
      <title>How I Finally Got Stable 60 FPS on Ubuntu laptop (NVIDIA + Intel)</title>
      <dc:creator>Ali Al Khawaja</dc:creator>
      <pubDate>Mon, 06 Apr 2026 20:09:07 +0000</pubDate>
      <link>https://dev.to/ali-alkhawaja/how-i-finally-got-stable-60-fps-on-ubuntu-laptop-nvidia-intel-3lif</link>
      <guid>https://dev.to/ali-alkhawaja/how-i-finally-got-stable-60-fps-on-ubuntu-laptop-nvidia-intel-3lif</guid>
      <description>&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;I’m running Ubuntu on an HP &lt;strong&gt;laptop&lt;/strong&gt; with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intel i5 (11th gen)&lt;/li&gt;
&lt;li&gt;NVIDIA MX350 (Optimus setup)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was using Steam with the latest Proton (10.0-4) to play Warframe (Gold-rated on ProtonDB), and CS2 (native Linux).&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Playing games on an Ubuntu &lt;strong&gt;laptop&lt;/strong&gt; was a horrible experience with an Nvidia GPU ,it was always mysterious and vague on why I had a terrible performance and inconsistent FPS problems .&lt;/p&gt;

&lt;p&gt;It wasn't like because Linux can't game like any one would've thought ,but because gaming on a Linux laptop is pain .&lt;/p&gt;

&lt;p&gt;I'm talking about having performance issues even on native Linux games which should not be possible unless if purposely slow down your laptop ,ahm ahm (yes it was that 🙄) &lt;/p&gt;

&lt;p&gt;I had CS2 and CSGO(in the past) which is a native game... and it was Lagging ,How ? How am I lagging? I even deleted proton to be sure .&lt;/p&gt;

&lt;p&gt;To be more clear ,most of the time I had my &lt;strong&gt;GPU usage on 100%&lt;/strong&gt; but with an average of 27 fps and a lot unbearable stuttering 🤨 ,the laptop's fan was not ramping up much ,it's didn't reach it's maximum speed ,I know what my laptop can &amp;amp; can't do since I used to play on windows before ,I should get a consistent 60 FPS on certain graphical settings on both Warframe and CSGO ,well now it's CS2.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Tried (and failed)
&lt;/h2&gt;

&lt;p&gt;I tried everything an average person would try:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I tired rebooting &lt;/li&gt;
&lt;li&gt;Not rebooting😆 (you should rebooting after switching  prime-profiles)&lt;/li&gt;
&lt;li&gt;Switching between Wayland from X11 &lt;/li&gt;
&lt;li&gt;Reinstalling NVIDIA drivers &lt;/li&gt;
&lt;li&gt;Switching distros &lt;/li&gt;
&lt;li&gt;Launching games with terminal commands to use specify use of the discrete card (NVIDIA) &lt;/li&gt;
&lt;li&gt;Changing some settings in the NVIDIA X server settings &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I still had my game stuttering and low FPS ,hmm&lt;/p&gt;

&lt;h2&gt;
  
  
  The Breakthrough &amp;amp; a small talk on power consumption
&lt;/h2&gt;

&lt;p&gt;The issue wasn't really in the GPU ,the real bottleneck was the CPU governor ,let me explain how I got there .&lt;/p&gt;

&lt;p&gt;Us laptop users care about the battery life and want to extend it much as possible.&lt;/p&gt;

&lt;p&gt;Those who have dual graphics cards with an Optimus setup , iGPU + GPU (NVIDIA in my case) ,so ,I do turn off my NVIDIA card when I don't want to play any games ,using &lt;code&gt;sudo prime-select intel&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;And because intel drivers are great on linux ,I go on my daily life with the iGPU on wayland because it works fine.&lt;/p&gt;

&lt;p&gt;Running the iGPU only has great benefits ,I get an average power consumption of 6W on idle and 10w~12w when multi tasking ,here I'm consuming 8.9w while having youtube running and other 9 chrome tabs open&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5ai4kowmnlq11ckaw9g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5ai4kowmnlq11ckaw9g.png" alt=" " width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's very acceptable rate to be honest and it will be lower if I'm reading or coding ,it really depends on how active I am in the real time.&lt;/p&gt;

&lt;p&gt;Okay here is that ,now to NVIDIA .&lt;/p&gt;

&lt;p&gt;If you're like me and tried to keep your GPU card run on-demand because you will play games this week ,you will immediately get an 9w on idle and 14w~17w when multi tasking ,that GPU drains a lot of energy ,go ahead and check power statistics .&lt;/p&gt;

&lt;p&gt;Well ,I would take that trade-off any time if I'm expecting a free time to play Warframe on-demand but it didn't work and I got a terrible performance ,I even tried performance mode ,only to consume more power and get no effects ,still lagging on NVIDIA ,I accepted it and blamed NVIDIA for not optimizing it's drivers which somewhat true ,hey ,if you wanna play ,just hop on windows🫤 ,that's what I thought until one day &lt;/p&gt;

&lt;p&gt;So here I am one day ,retrying on-demand prime-profile after updating my NVIDIA drivers to the latest new version .&lt;br&gt;
I got a terrible app loading time on system apps ,apps like settings ,umm hello? what is happening? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F49jy5yhc85t4l0y6q11i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F49jy5yhc85t4l0y6q11i.png" alt=" " width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I always had almost 1 second loading time or even less when I had intel iGPU only on ,why is it taking more when I have my NVIDIA GPU on-demand ,it should have been faster.&lt;/p&gt;

&lt;p&gt;So I jumped to ask an AI and gave it some logs ,it said that most of my systems are working normally :&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;✅ NVIDIA kernel modules are loading (driver version 580.126.09) &lt;/li&gt;
&lt;li&gt;✅ NVIDIA Persistence Daemon is running&lt;/li&gt;
&lt;li&gt;✅ NVIDIA modesetting driver is loaded&lt;/li&gt;
&lt;li&gt;✅ Xorg is detecting and attempting to use the NVIDIA driver&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Issues Detected:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Critical DRM Errors (Lines 15-16):&lt;/li&gt;
&lt;/ol&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nvidia 0000:01:00.0: [drm] No compatible format found
nvidia 0000:01:00.0: [drm] Cannot find any crtc or sizes
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;And some other issues ,four in total ,they don't matter for now.&lt;br&gt;
It also said :&lt;/p&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The key issue: In on-demand mode, the NVIDIA GPU is essentially "asleep" until an application requests it. But the DRM subsystem is trying to initialize it at boot and failing because it can't find a display connected to it . This causes those No compatible format found errors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's how to fix this:&lt;br&gt;
Immediate Fix: Switch to NVIDIA Mode....&lt;/p&gt;


&lt;/blockquote&gt;

&lt;p&gt;or blah blah blah ,Enable modesetting for NVIDIA ,Add kernel parameters: blah blah blah Test Application Offloading blah blah ,Create a minimal Xorg configuration for on-demand mode something something .&lt;/p&gt;

&lt;p&gt;I have no idea what it was talking about ,but we don't need any of that because the solution is very simple🙂.&lt;/p&gt;

&lt;p&gt;I had to stop the AI from overthinking and gave it all my notes on all behaviors I noticed happening in my system ,that helps AI a lot.&lt;/p&gt;

&lt;p&gt;At the end ,It's all because of power modes .The GPU isn't the main factor ,the real bottleneck is the CPU governor but it's not that simple unless you know.&lt;/p&gt;

&lt;p&gt;here is some data I got after running some tests on each power-mode using &lt;code&gt;time gnome-control-center&lt;/code&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;CPU Governor&lt;/th&gt;
&lt;th&gt;Settings Open Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Intel&lt;/td&gt;
&lt;td&gt;powersave&lt;/td&gt;
&lt;td&gt;3.5s - 4.0s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intel&lt;/td&gt;
&lt;td&gt;performance&lt;/td&gt;
&lt;td&gt;1.8s - 2.1s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA&lt;/td&gt;
&lt;td&gt;powersave&lt;/td&gt;
&lt;td&gt;2.3s - 2.4s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA&lt;/td&gt;
&lt;td&gt;performance&lt;/td&gt;
&lt;td&gt;? (probably ~1.5s)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Step-by-Step Fix
&lt;/h2&gt;

&lt;p&gt;I will take the AI's words here and paste them here since it explains it better than me :&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  The Root Cause
&lt;/h3&gt;

&lt;p&gt;On Optimus laptops, the NVIDIA GPU doesn't directly connect to the display - it renders frames and passes them through the Intel GPU. This causes two main issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;DRM errors are NORMAL - The "No compatible format found" errors happen because NVIDIA tries to initialize a display controller that doesn't exist. They're harmless!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CPU governor is the REAL culprit - Even when you select "Performance" mode in GNOME, the actual CPU governor often stays on powersave, causing 2-4 second delays in app launches.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My comment here: Gnome power profiles are not always true, you can set you laptop's power profile on performance but still have the CPU governor on powersave , gnome power profile lies? .&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/li&gt;

&lt;/ol&gt;
&lt;br&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Proper GPU Switching
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

set_governor&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Setting CPU governor to &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;..."&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /sys/devices/system/cpu/cpu&lt;span class="k"&gt;*&lt;/span&gt;/cpufreq/scaling_governor
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Current governor:"&lt;/span&gt;
    &lt;span class="nb"&gt;cat&lt;/span&gt; /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Select GPU Mode:"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"1) Intel (Power Saving)"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"2) NVIDIA (Performance)"&lt;/span&gt;
&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Enter choice [1 or 2]: "&lt;/span&gt; choice

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$choice&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Switching to Intel mode and power-saver profile..."&lt;/span&gt;
    &lt;span class="nb"&gt;sudo &lt;/span&gt;prime-select intel
    powerprofilesctl &lt;span class="nb"&gt;set &lt;/span&gt;power-saver
    set_governor &lt;span class="s2"&gt;"powersave"&lt;/span&gt;

&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$choice&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"2"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Switching to NVIDIA mode and performance profile..."&lt;/span&gt;
    &lt;span class="nb"&gt;sudo &lt;/span&gt;prime-select nvidia
    powerprofilesctl &lt;span class="nb"&gt;set &lt;/span&gt;performance
    set_governor &lt;span class="s2"&gt;"performance"&lt;/span&gt;

    &lt;span class="c"&gt;# Also set energy_performance_preference for intel_pstate&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /sys/devices/system/cpu/intel_pstate/energy_performance_preference &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"performance"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /sys/devices/system/cpu/intel_pstate/energy_performance_preference
    &lt;span class="k"&gt;fi&lt;/span&gt;

    &lt;span class="c"&gt;# Set each CPU's energy preference&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;cpu &lt;span class="k"&gt;in&lt;/span&gt; /sys/devices/system/cpu/cpu&lt;span class="k"&gt;*&lt;/span&gt;/power/energy_perf_bias&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"performance"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nv"&gt;$cpu&lt;/span&gt; 2&amp;gt;/dev/null
    &lt;span class="k"&gt;done
else
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Invalid choice."&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Final verification:"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"GPU Mode: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;prime-select query&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Power Profile: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;powerprofilesctl get&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"CPU Governor: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Done. Please reboot for changes to take full effect."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;DRM errors are red herrings ,don't waste time fixing them on Optimus laptops.&lt;/li&gt;
&lt;li&gt;CPU governor matters more than you think ,powersave can add 2-3 seconds to app launches because it will slow down everything to save power ,it works so well.&lt;/li&gt;
&lt;li&gt;GNOME's power profiles &lt;strong&gt;don't&lt;/strong&gt; always set the CPU governor ,&lt;strong&gt;You need to do it manually&lt;/strong&gt; if you know you are gaming soon.&lt;/li&gt;
&lt;li&gt;Systemd services are your friend ,use them to enforce settings across reboots.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Credits
&lt;/h4&gt;

&lt;p&gt;This solution was developed through collaborative troubleshooting with DeepSeek AI, an incredible coding assistant that helped diagnose the real issues, understand the logs, and craft these practical solutions.&lt;/p&gt;




&lt;p&gt;Yeah yeah AI is helpful but here is what you should know as rule of thumb:&lt;/p&gt;

&lt;p&gt;On intel only, the intel prime-profile &lt;code&gt;prime-select intel&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Power Saving profile: System slows down (~3-4s app launch), great battery life (4+ hours) &lt;/li&gt;
&lt;li&gt;Performance profile: System speeds up (~1.8s app launch), but uses more battery.&lt;/li&gt;
&lt;li&gt;Verdict: GNOME power profiles actually work here! Switching between powersave/performance changes CPU behavior noticeably.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On NVIDIA only ,the NVIDIA prime-profile &lt;code&gt;prime-select nvidia&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Without fixes: System slow (~3s) even with "Performance" selected in GNOME power modes.&lt;/li&gt;
&lt;li&gt;With our fixes: System fast (~1.5s), gaming at 60 FPS&lt;/li&gt;
&lt;li&gt;Verdict: GNOME power profiles are IGNORED here for some reason ,you must manually set CPU governor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On on-demand , the on-demand prime-profile  &lt;code&gt;prime-select on-demand&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What should happen: Desktop runs on Intel (saving power), games auto-switch to NVIDIA&lt;/li&gt;
&lt;li&gt;What actually happens:

&lt;ul&gt;
&lt;li&gt;Desktop is slow (CPU stuck on power-save)&lt;/li&gt;
&lt;li&gt;Games don't properly activate NVIDIA (30 FPS instead of 60)&lt;/li&gt;
&lt;li&gt;Worst of both worlds - no battery savings AND no performance&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Verdict: Great idea in theory, but implementation needs work, the NVIDIA drivers for linux laptops could be improved on Ubuntu laptops .&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Moral of the Story
&lt;/h2&gt;

&lt;p&gt;Linux on Optimus laptops is almost there. The hardware works, the drivers work, but the integration between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prime-select (GPU switching)&lt;/li&gt;
&lt;li&gt;powerprofilesctl (GNOME power profiles)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CPU governors&lt;br&gt;
It is still a bit rough. Until it's polished, manual control with simple scripts is the way to go. &lt;/p&gt;
&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stable 60 FPS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No stuttering&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fans behaving normally&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The laptop is using its full power.&lt;/p&gt;
&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;One thing I didn’t expect to learn:&lt;br&gt;
Windows handles all of this silently and you only realize how much work it’s doing when you switch away from it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On Linux, you get control… but sometimes you have to earn it.&lt;/p&gt;

&lt;p&gt;bye ,see you later.&lt;/p&gt;

</description>
      <category>nvidia</category>
      <category>ubuntu</category>
      <category>linux</category>
      <category>beginners</category>
    </item>
    <item>
      <title>DOM Manipulation Refresher - AI written</title>
      <dc:creator>Ali Al Khawaja</dc:creator>
      <pubDate>Sat, 05 Jul 2025 19:56:56 +0000</pubDate>
      <link>https://dev.to/ali-alkhawaja/dom-manipulation-refresher-ai-written-4iia</link>
      <guid>https://dev.to/ali-alkhawaja/dom-manipulation-refresher-ai-written-4iia</guid>
      <description>&lt;h2&gt;
  
  
  1. Selecting Elements
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// By ID&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// By class (returns NodeList)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementsByClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-class&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// By tag (returns HTMLCollection)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;divs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementsByTagName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Modern selectors (returns first match)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#content p.intro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Returns NodeList of all matches&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.items&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Modifying Content
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Replace all content (parses HTML)&lt;/span&gt;
&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;strong&amp;gt;New content&amp;lt;/strong&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Just text (safer against XSS)&lt;/span&gt;
&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Plain text content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// For form elements&lt;/span&gt;
&lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;New value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Creating and Adding Elements
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create new element&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newParagraph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;p&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;newParagraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A new paragraph&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Append to end&lt;/span&gt;
&lt;span class="nx"&gt;contentDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newParagraph&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Insert before another element&lt;/span&gt;
&lt;span class="nx"&gt;contentDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newParagraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;existingElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Insert adjacent HTML (more flexible)&lt;/span&gt;
&lt;span class="nx"&gt;contentDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertAdjacentHTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;beforeend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;p&amp;gt;New paragraph&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Positions: 'beforebegin', 'afterbegin', 'beforeend', 'afterend'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Best Practice Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Instead of innerHTML (which can have security risks), you can:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contentDiv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Clear existing content&lt;/span&gt;
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contentDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;contentDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contentDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create and append new elements&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;heading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Section Title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;contentDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paragraph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;p&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;paragraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is a paragraph of text.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;contentDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paragraph&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Event Handling
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;contentDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Div was clicked!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>brain dump - Webpack Revision</title>
      <dc:creator>Ali Al Khawaja</dc:creator>
      <pubDate>Tue, 01 Jul 2025 15:21:53 +0000</pubDate>
      <link>https://dev.to/ali-alkhawaja/webpack-revision-550g</link>
      <guid>https://dev.to/ali-alkhawaja/webpack-revision-550g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“⚠️ This is a personal reference post — not a full guide.”&lt;br&gt;
Hi reader .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Lesson overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why do we need webpack for our project ?&lt;/li&gt;
&lt;li&gt;How to start web-packing ?&lt;/li&gt;
&lt;li&gt;Reading WebPack guide online .&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why do we need webpack for our project ?
&lt;/h3&gt;

&lt;p&gt;You can ask Chatgpt for the answer or just visit the &lt;a href="https://webpack.js.org/concepts/" rel="noopener noreferrer"&gt;introduction&lt;/a&gt; page. &lt;br&gt;
I don't want to add it here because this is a revision, I would however say that we use Webpack for :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It's Module Bundling&lt;/li&gt;
&lt;li&gt;It's Code Splitting&lt;/li&gt;
&lt;li&gt;It's Asset Management&lt;/li&gt;
&lt;li&gt;It's Transpilation&lt;/li&gt;
&lt;li&gt;It's Hot Module Replacement&lt;/li&gt;
&lt;li&gt;It's Plugins&lt;/li&gt;
&lt;li&gt;It's Development and Production Modes&lt;/li&gt;
&lt;li&gt;It's Configuration Flexibility&lt;/li&gt;
&lt;li&gt;It's Community and Ecosystem&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  How to start web-packing ?
&lt;/h2&gt;

&lt;p&gt;Step 1: you need a &lt;code&gt;package.json&lt;/code&gt; file, so, you should make one by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init - y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if you see a type tag in the &lt;code&gt;package.json&lt;/code&gt; like &lt;code&gt;"type": "commonjs"&lt;/code&gt; , remove it . &lt;/p&gt;

&lt;p&gt;Step 2: You install webpack&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; webpack webpack-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We included the --save-dev flag (you can also use -D as a shortcut), which tells npm to record our two packages as development dependencies.&lt;/p&gt;

&lt;p&gt;Step 3 : Create a configuration file, you can name it &lt;code&gt;webpack.config.js&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Step 4 : make a configuration !&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// webpack.config.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;main.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't know how to make a configuration file? &lt;a href="https://webpack.js.org/guides/getting-started/#using-a-configuration" rel="noopener noreferrer"&gt;read this&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dealing with HTML files ?
&lt;/h2&gt;

&lt;p&gt;we use &lt;code&gt;HtmlWebpackPlugin&lt;/code&gt;&lt;br&gt;
Install it &lt;code&gt;npm install --save-dev html-webpack-plugin&lt;/code&gt; then add this block :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HtmlWebpackPlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/template.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;read about it &lt;a href="https://webpack.js.org/plugins/html-webpack-plugin/#root" rel="noopener noreferrer"&gt;here&lt;/a&gt; &lt;br&gt;
then &lt;code&gt;npx webpack&lt;/code&gt; , this command runs webpack&lt;/p&gt;
&lt;h2&gt;
  
  
  Dealing with CSS ?
&lt;/h2&gt;

&lt;p&gt;Install a plugin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev style-loader css-loader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Dealing with images ?
&lt;/h2&gt;

&lt;p&gt;Install a plugin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev html-loader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get the idea now do you ? it is all in the docs&lt;/p&gt;

&lt;p&gt;Anyways lets talk about webpack dev server &lt;br&gt;
Install it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev webpack-dev-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx webpack serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read about it &lt;a href="https://webpack.js.org/configuration/dev-server/" rel="noopener noreferrer"&gt;here&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  where to find guides ?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://webpack.js.org/guides/" rel="noopener noreferrer"&gt;Here&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you think this post is pointless then you would be right, honestly I write just to make stuff stick in my head , I know that nobody is gonna read this anyways.&lt;/p&gt;

&lt;p&gt;It's just a tool 🤷‍♂️&lt;br&gt;
I will try to pick an interesting subject next time😔.&lt;br&gt;
Bye&lt;/p&gt;

</description>
      <category>webpack</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Quick OOP refresher for Ruby- Draft 1</title>
      <dc:creator>Ali Al Khawaja</dc:creator>
      <pubDate>Sat, 26 Apr 2025 12:04:51 +0000</pubDate>
      <link>https://dev.to/ali-alkhawaja/quick-oop-refresher-for-ruby-1b48</link>
      <guid>https://dev.to/ali-alkhawaja/quick-oop-refresher-for-ruby-1b48</guid>
      <description>&lt;h2&gt;
  
  
  Ruby Object Oriented Programming 📦 - Refresher
&lt;/h2&gt;




&lt;h3&gt;
  
  
  What are Objects ?
&lt;/h3&gt;

&lt;p&gt;Objects are what classes make.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to create an object ?
&lt;/h3&gt;

&lt;p&gt;Creating an object is easy, you create a class then you  instantiate it to make an object,below is an example of an object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NormalCat&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;chips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NormalCat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Chips"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# This create a a cat 🐈 object named "chips"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  What is OOP ?
&lt;/h3&gt;

&lt;p&gt;OOP is a programming paradigm that manages the complexity of large software systems, this paradigm helps us avoid the debugging hell that happens just because we changed some code. tell me about neck pain he said😮‍💨.&lt;/p&gt;

&lt;p&gt;OOP helps us by sectioning off a bunch of code to objects that can talk with each other instead of making everything in one mountain ⛰️&lt;/p&gt;

&lt;h3&gt;
  
  
  How does OOP make our life easier ?
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;By Encapsulation&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The concepts of Encapsulation is that we combine &lt;strong&gt;variables&lt;/strong&gt; and &lt;strong&gt;methods&lt;/strong&gt; that work with &lt;strong&gt;the data&lt;/strong&gt; into an object. &lt;/p&gt;

&lt;p&gt;By other words, by using encapsulated object OOP makes our life easier.&lt;/p&gt;

&lt;p&gt;Again, by storing &lt;strong&gt;variables&lt;/strong&gt; and &lt;strong&gt;methods&lt;/strong&gt; that work with some data in an object you encapsulate them, with this you get the power of hiding 😶‍🌫️ the code from other objects, this means nothing can manipulate your hidden code unless you want to, you can expose your object to other objects by using methods to interact with other objects. like setter and getters.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Inheritance
&lt;/h3&gt;

&lt;p&gt;It's when when a class inherit the behaviors of another class aka the super-class&lt;/p&gt;

&lt;h3&gt;
  
  
  Polymorphism
&lt;/h3&gt;

&lt;p&gt;Polymorphism is a core concept in OOP that allows objects of different classes to respond to the same method call in different ways.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;speak&lt;/span&gt;
    &lt;span class="s2"&gt;"Some sound"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Animal&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;speak&lt;/span&gt;  &lt;span class="c1"&gt;# Overrides Animal#speak&lt;/span&gt;
    &lt;span class="s2"&gt;"Woof!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Animal&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;speak&lt;/span&gt;  &lt;span class="c1"&gt;# Overrides Animal#speak&lt;/span&gt;
    &lt;span class="s2"&gt;"Meow!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;animals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;speak&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# Output:&lt;/span&gt;
&lt;span class="c1"&gt;# Woof!&lt;/span&gt;
&lt;span class="c1"&gt;# Meow!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Modules
&lt;/h3&gt;

&lt;p&gt;It's another way to inherit behavior but this it is different because we don't make objects out of module but rather just plug them into an object by using &lt;code&gt;include&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Debuggable&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;debug_info&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; - Object ID: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;object_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Debuggable&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Debuggable&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Laptop"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;debug_info&lt;/span&gt;  &lt;span class="c1"&gt;# Output: Product - Object ID: 70307294386140&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;debug_info&lt;/span&gt;     &lt;span class="c1"&gt;# Output: User - Object ID: 70307294386120&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  More on classes and objects
&lt;/h3&gt;

&lt;h4&gt;
  
  
  initialize method
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NormalCat&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"This object was initialized!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;chips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NormalCat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Chips"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;# =&amp;gt; "This object was initialized!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a methods that gets initialized at object creation.&lt;br&gt;
You may know it as the constructor.&lt;/p&gt;
&lt;h4&gt;
  
  
  Instance variables
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NormalCat&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;@name&lt;/code&gt; is an &lt;strong&gt;instance&lt;/strong&gt; variable. It is a variable that exists as long as the object instance exists&lt;/p&gt;
&lt;h4&gt;
  
  
  Instance Methods
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NormalCat&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;speak&lt;/span&gt;
    &lt;span class="s2"&gt;"meow!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;chips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NormalCat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Chips"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;chips&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;speak&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "meow!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Class methods
&lt;/h4&gt;

&lt;p&gt;They are not instance methods, class methods are methods we can call directly on the class itself without having to instantiate any object&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;something&lt;/span&gt;
  &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"nothing"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we just call it on a class &lt;code&gt;cat.something&lt;/code&gt; --&amp;gt; "nothing", class methods are best when it does not need to deal with the state of the data.&lt;/p&gt;

&lt;h4&gt;
  
  
  Class variables
&lt;/h4&gt;

&lt;p&gt;just like class methods but as variables, you can create a class variable using two @@ &lt;/p&gt;

&lt;h3&gt;
  
  
  Composition and Aggregation
&lt;/h3&gt;

&lt;p&gt;We talked about making objects talk with each other but how ? there are some design principles used to establish relationships between classes. &lt;br&gt;
Both composition and aggregation involve using instance variables to hold references to other objects, but they differ in terms of the lifecycle and ownership of the objects involved.&lt;/p&gt;
&lt;h4&gt;
  
  
  Composition
&lt;/h4&gt;

&lt;p&gt;composition is a relationship where an object contain other objects as part of its state , they depend on each other. If you destroy the container it will also destroy it's other contained objects&lt;/p&gt;

&lt;p&gt;It's easy to implement composition, you only have to use instance variables . Here is an example :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Engine starting..."&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;  &lt;span class="c1"&gt;# Engine instance is created when Car is created&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;
    &lt;span class="vi"&gt;@engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;my_car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;my_car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;  &lt;span class="c1"&gt;# Engine is an integral part of Car&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example &lt;code&gt;Car&lt;/code&gt; object has initialized an instance variables that contains the &lt;code&gt;Engine&lt;/code&gt; object, this gives the &lt;code&gt;Car&lt;/code&gt; an &lt;code&gt;Engine&lt;/code&gt; with all of it's powers/properties .&lt;br&gt;
Remember, objects live and die together.&lt;/p&gt;

&lt;p&gt;Did you know ? Godot uses Composition for it nodes for building games ! &lt;/p&gt;
&lt;h3&gt;
  
  
  Aggregation
&lt;/h3&gt;

&lt;p&gt;Aggregation is a less restrictive design principle because contained object do not live and die with container object.&lt;br&gt;
This is possible because the container only references the contained objects. Here is an example :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Passenger&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passengers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="vi"&gt;@passengers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;passengers&lt;/span&gt;  &lt;span class="c1"&gt;# Passengers are given to the Car at creation&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Passengers can exist without Car&lt;/span&gt;
&lt;span class="n"&gt;passengers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Passenger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Passenger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;my_car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passengers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;Car.new&lt;/code&gt; gets an array of passengers at creation, those passengers are independent from the car, this means that we can pass the passengers in the Car at as long as the Car object is alive.&lt;/p&gt;

&lt;h4&gt;
  
  
  Container Object relations to instance variables
&lt;/h4&gt;

&lt;p&gt;The relationships between a container class instance and its composed and aggregated objects is implemented with instance variables. These instance variables hold references to other objects, enabling the container class to access and interact with the contained object's methods and properties. The main difference lies in the ownership and the lifecycle of the objects referenced by these instance variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Composition: The container owns the contained objects, and their lifecycles are tightly linked.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  - Aggregation: The container does not own the contained objects; they can exist independently.
&lt;/h2&gt;

&lt;p&gt;These concepts are fundamental in designing systems that are modular, where changes to one part of the system do not unduly affect others.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;speak&lt;/code&gt; is an instance methods&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessor Methods
&lt;/h3&gt;

&lt;p&gt;lets say that we have this cat , how can we know the name of the cat?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NormalCat&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;speak&lt;/span&gt;
    &lt;span class="s2"&gt;"meow!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;orange_cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NormalCat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"chonk"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;chips&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;speak&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "meow!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;let us try &lt;code&gt;puts orange_cat.name&lt;/code&gt;, oh no we got a :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;undefined method `name' for an instance of NormalCat (NoMethodError)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to access the orange_cat's name, which is stored in the &lt;a class="mentioned-user" href="https://dev.to/name"&gt;@name&lt;/a&gt; instance variable, we have to create a method that will return the name. We can call it get_name, and its only job is to return the value in the &lt;a class="mentioned-user" href="https://dev.to/name"&gt;@name&lt;/a&gt; instance variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NormalCat&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;speak&lt;/span&gt;
    &lt;span class="s2"&gt;"meow!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_name&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="c1"&gt;# instance variable&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;orange_cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NormalCat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"chonk"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;orange_cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;speak&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "meow!"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;orange_cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_name&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "chonk"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;okay but what if we want to change orange_cat's name ? then we make a setter method !&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NormalCat&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;speak&lt;/span&gt;
    &lt;span class="s2"&gt;"meow!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_name&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="c1"&gt;# instance variable&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;orange_cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NormalCat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"chonk"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;orange_cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;speak&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "meow!"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;orange_cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_name&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "chonk"&lt;/span&gt;
&lt;span class="n"&gt;orange_cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"kurt"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;orange_cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;attr_accessor&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Ruby has a built-in way to automatically create these getter and setter methods for us, using the attr_accessor method.&lt;/p&gt;

&lt;p&gt;The attr_accessor method takes a symbol as an argument, which it uses to create the method name for the getter and setter&lt;br&gt;
methods.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;**attr_reader**&lt;/code&gt;&lt;br&gt;
It's a getter only&lt;br&gt;
&lt;code&gt;**attr_writer**&lt;/code&gt;&lt;br&gt;
It's a setter only.&lt;/p&gt;

&lt;p&gt;All of the attr_* methods take Symbol objects as arguments; if there are more states you're tracking, you can use this syntax: &lt;code&gt;attr_accessor :name, :height, :weight&lt;/code&gt;&lt;br&gt;
try to use &lt;code&gt;self&lt;/code&gt; with attr_accessor has created to the job of instance methods to let Ruby know that we are calling the methods and that we are not defining a new local variables ! &lt;/p&gt;

&lt;p&gt;Note , try not to use a instance variables outside of the initialize constructor , use an instance methods that can use from attr_accessor  aka getters and setters and store them in a methods , it's better for maintaining clean code.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Instance methods can call other instance methods, instance variables, class methods, or class variables</title>
      <dc:creator>Ali Al Khawaja</dc:creator>
      <pubDate>Wed, 29 Jan 2025 18:31:44 +0000</pubDate>
      <link>https://dev.to/ali-alkhawaja/instance-methods-can-call-other-instance-methods-instance-variables-class-methods-or-class-2m3p</link>
      <guid>https://dev.to/ali-alkhawaja/instance-methods-can-call-other-instance-methods-instance-variables-class-methods-or-class-2m3p</guid>
      <description></description>
      <category>oop</category>
    </item>
    <item>
      <title>Class methods have access to other class methods and class variables but don’t have access to instance methods or instance variables</title>
      <dc:creator>Ali Al Khawaja</dc:creator>
      <pubDate>Wed, 29 Jan 2025 18:29:35 +0000</pubDate>
      <link>https://dev.to/ali-alkhawaja/class-methods-have-access-to-other-class-methods-and-class-variables-but-dont-have-access-to-50i9</link>
      <guid>https://dev.to/ali-alkhawaja/class-methods-have-access-to-other-class-methods-and-class-variables-but-dont-have-access-to-50i9</guid>
      <description></description>
    </item>
    <item>
      <title>In Ruby,`attr_accessor` is helper method that takes symbols to create a setter and a getter quickly for desired variable names, it's really helpful .</title>
      <dc:creator>Ali Al Khawaja</dc:creator>
      <pubDate>Wed, 29 Jan 2025 18:02:39 +0000</pubDate>
      <link>https://dev.to/ali-alkhawaja/in-rubyattraccessor-is-helper-method-that-takes-symbols-to-create-a-setter-and-a-getter-quickly-1phg</link>
      <guid>https://dev.to/ali-alkhawaja/in-rubyattraccessor-is-helper-method-that-takes-symbols-to-create-a-setter-and-a-getter-quickly-1phg</guid>
      <description></description>
      <category>ruby</category>
    </item>
    <item>
      <title>In OOP, instance variables are part of an instanced object but you can't access them from outside of the instanced object, to solve this problem we use setters and getters.</title>
      <dc:creator>Ali Al Khawaja</dc:creator>
      <pubDate>Wed, 29 Jan 2025 17:54:28 +0000</pubDate>
      <link>https://dev.to/ali-alkhawaja/in-oop-instance-variables-are-part-of-an-instanced-object-but-you-cant-access-them-from-outside-ee6</link>
      <guid>https://dev.to/ali-alkhawaja/in-oop-instance-variables-are-part-of-an-instanced-object-but-you-cant-access-them-from-outside-ee6</guid>
      <description></description>
      <category>webdev</category>
      <category>oop</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to make multidimensional / 2D Arrays &amp; Hashes in Ruby ?</title>
      <dc:creator>Ali Al Khawaja</dc:creator>
      <pubDate>Wed, 08 Jan 2025 22:27:11 +0000</pubDate>
      <link>https://dev.to/ali-alkhawaja/how-to-make-multidimensional-2d-arrays-hashes-in-ruby--4g5n</link>
      <guid>https://dev.to/ali-alkhawaja/how-to-make-multidimensional-2d-arrays-hashes-in-ruby--4g5n</guid>
      <description>&lt;h2&gt;
  
  
  Arrays
&lt;/h2&gt;

&lt;p&gt;A multidimensional array is a collection of data organized in multiple dimensions, such as a grid or table. It allows you to store and access data in a structured way, like rows and columns in a spreadsheet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nested Arrays (Multidimensional Arrays)
&lt;/h3&gt;

&lt;p&gt;A nested array is an array where each element is itself an array. This creates a structure similar to rows and columns in a spreadsheet.&lt;/p&gt;

&lt;h4&gt;
  
  
  Accessing Elements
&lt;/h4&gt;

&lt;p&gt;Elements in a nested array are accessed using multiple indices: &lt;code&gt;array[row_index][column_index]&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;nestedArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;nestedArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Output: 2 (accesses the element at row 0, column 1)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;nestedArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Output: 9 (accesses the element at row 2, column 2)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use negative indices to access elements from the end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;nestedArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Output: 9 (last row, last element)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Handling Missing Rows or Columns
&lt;/h4&gt;

&lt;p&gt;Attempting to access a non-existent row using &lt;code&gt;array[row_index]&lt;/code&gt; will result in a &lt;code&gt;NoMethodError&lt;/code&gt; because &lt;code&gt;nil&lt;/code&gt; (the value for a missing row) doesn't respond to the &lt;code&gt;[]&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;To avoid this, use the &lt;code&gt;.dig(row_index, column_index)&lt;/code&gt; method. It safely returns &lt;code&gt;nil&lt;/code&gt; if any part of the path is invalid, preventing errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;nestedArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;nestedArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Output: nil (row 2 doesn't exist)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;nestedArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Output: nil (column 5 doesn't exist in row 0)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Accessing a non-existent column in an existing row (e.g., &lt;code&gt;nestedArray[0][5]&lt;/code&gt;) will return &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating Nested Arrays
&lt;/h4&gt;

&lt;p&gt;When creating nested arrays, it's crucial to use a block with &lt;code&gt;Array.new&lt;/code&gt; to avoid unintended sharing of inner arrays:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Correct: Creates distinct inner arrays&lt;/span&gt;
&lt;span class="n"&gt;nested_array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Incorrect: All inner arrays reference the same object&lt;/span&gt;
&lt;span class="n"&gt;incorrect_nested&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# Avoid this!&lt;/span&gt;

&lt;span class="n"&gt;incorrect_nested&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"changed"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;incorrect_nested&lt;/span&gt; &lt;span class="c1"&gt;# Output: [["changed", nil], ["changed", nil], ["changed", nil]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The incorrect example demonstrates the issue of creating nested arrays without a block. All the inner arrays point to the same object in memory, meaning changing one changes them all.&lt;/p&gt;

&lt;h4&gt;
  
  
  Adding and Removing Elements
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Adding:&lt;/strong&gt; Use &lt;code&gt;push&lt;/code&gt; to add elements to the end of a row: &lt;code&gt;nested_array[row_index].push(value)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Removing:&lt;/strong&gt; Use &lt;code&gt;pop&lt;/code&gt; to remove the last element from a row: &lt;code&gt;nested_array[row_index].pop&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Iterating Over Nested Arrays
&lt;/h4&gt;

&lt;p&gt;Use nested &lt;code&gt;each_with_index&lt;/code&gt; loops to iterate over rows and columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_with_index&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row_index&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_with_index&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col_index&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Element at [&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;row_index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;col_index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Nested Hashes
&lt;/h3&gt;

&lt;p&gt;Nested hashes are hashes where the values are themselves hashes. This is useful for representing structured data with key-value relationships within key-value relationships.&lt;/p&gt;

&lt;h4&gt;
  
  
  Accessing Data
&lt;/h4&gt;

&lt;p&gt;Access data using chained keys: &lt;code&gt;hash[:outer_key][:inner_key]&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;vehicles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;alice: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;year: &lt;/span&gt;&lt;span class="mi"&gt;2019&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;make: &lt;/span&gt;&lt;span class="s2"&gt;"Toyota"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;model: &lt;/span&gt;&lt;span class="s2"&gt;"Corolla"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="ss"&gt;bob: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;year: &lt;/span&gt;&lt;span class="mi"&gt;2022&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;make: &lt;/span&gt;&lt;span class="s2"&gt;"Tesla"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;model: &lt;/span&gt;&lt;span class="s2"&gt;"Model 3"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;vehicles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:alice&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:model&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Output: Corolla&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;dig&lt;/code&gt; to safely access nested values and avoid &lt;code&gt;NoMethodError&lt;/code&gt; if a key is missing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;vehicles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:charlie&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Output: nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Adding and Removing Data
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Adding:&lt;/strong&gt; Assign a new hash to a key: &lt;code&gt;hash[:new_key] = { key1: value1, key2: value2 }&lt;/code&gt;. Add to a nested hash: &lt;code&gt;hash[:outer_key][:new_inner_key] = value&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Removing:&lt;/strong&gt; Use &lt;code&gt;delete&lt;/code&gt; to remove a key-value pair: &lt;code&gt;hash.delete(:key)&lt;/code&gt; or &lt;code&gt;hash[:outer_key].delete(:inner_key)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Important Methods for Collections (Arrays and Hashes)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;select&lt;/code&gt;: Returns a new collection containing elements that satisfy a given condition.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;collect&lt;/code&gt; (or &lt;code&gt;map&lt;/code&gt;): Returns a new collection by transforming each element.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;compact&lt;/code&gt;: Returns a new array with all &lt;code&gt;nil&lt;/code&gt; elements removed.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;filter_map&lt;/code&gt;: Combines &lt;code&gt;filter&lt;/code&gt; (select) and &lt;code&gt;map&lt;/code&gt; in one step.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;You may notice that this guide is a bit weird , I tried something new , I  took my note an told GeminiAI to rewrite it. and I already dislike it 😮‍💨&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ruby</category>
      <category>programming</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to debug Ruby code ?</title>
      <dc:creator>Ali Al Khawaja</dc:creator>
      <pubDate>Sat, 04 Jan 2025 20:13:12 +0000</pubDate>
      <link>https://dev.to/ali-alkhawaja/how-to-debug-ruby-code--2dog</link>
      <guid>https://dev.to/ali-alkhawaja/how-to-debug-ruby-code--2dog</guid>
      <description>&lt;p&gt;Debugging Ruby &lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging by reading the stack trace
&lt;/h2&gt;

&lt;p&gt;it's when you get an error at runtime , this is the easiest form of error you can get in development , you will always be given the error name and at what line it occurred with a brief explanation of the problem .&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging with &lt;code&gt;puts&lt;/code&gt; or &lt;code&gt;p&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;When the code works and you get unexpected results then the easiest and quickest way to confirm your assumptions while debugging is by using &lt;code&gt;puts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Don't use puts because if you debug anything that is &lt;code&gt;nil&lt;/code&gt;or empty then it will give you a blank line , unlike &lt;code&gt;p&lt;/code&gt; , &lt;code&gt;p&lt;/code&gt; will tell you that it's &lt;code&gt;nil&lt;/code&gt;  &lt;/p&gt;

&lt;p&gt;example :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;puts "Using puts:"
puts []
p "Using p:"
p []
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Debugging with Pry-byebug
&lt;/h2&gt;

&lt;p&gt;an easier way of debugging is by using pry-byebug , after you install it , you to add&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require 'pry-byebug' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;at the top of your script  and the call &lt;code&gt;binding.pry&lt;/code&gt; as if it's a break-point somewhere in you program 🙂 , after you run your code you will be given something like IRB in your terminal to debug your code , keep in mind is that you stoped your program at that point anything after it is unknown for the debugger .&lt;/p&gt;

&lt;p&gt;you can find usual debugging commands like next and break here at &lt;a href="https://github.com/deivid-rodriguez/pry-byebug?tab=readme-ov-file#commands" rel="noopener noreferrer"&gt;https://github.com/deivid-rodriguez/pry-byebug?tab=readme-ov-file#commands&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging using VScode rdbg Ruby Debugger
&lt;/h2&gt;

&lt;p&gt;create a launch.json for your project and select Ruby(rdbg) when prompted , it's like chrome developer tools but for ruby . &lt;br&gt;
read more about it here :&lt;br&gt;
 &lt;a href="https://github.com/ruby/vscode-rdbg?tab=readme-ov-file#readme" rel="noopener noreferrer"&gt;https://github.com/ruby/vscode-rdbg?tab=readme-ov-file#readme&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to set-up Ruby &amp; Gems paths - Ruby snap package version</title>
      <dc:creator>Ali Al Khawaja</dc:creator>
      <pubDate>Fri, 18 Oct 2024 14:34:22 +0000</pubDate>
      <link>https://dev.to/ali-alkhawaja/how-to-set-up-ruby-gems-paths-ruby-snap-package-version-54hg</link>
      <guid>https://dev.to/ali-alkhawaja/how-to-set-up-ruby-gems-paths-ruby-snap-package-version-54hg</guid>
      <description>&lt;p&gt;&lt;strong&gt;Hi&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This post is for the developers that want to use ruby the snap version .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lets start &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1.0: Delete the old Install&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have tried to install Ruby the snap packaged version and faced problems using gems in VSCode or what ever then you need to remove them&lt;/p&gt;

&lt;p&gt;Do this to remove Ruby -&amp;gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;snap remove ruby
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or &lt;/p&gt;

&lt;p&gt;just remove Ruby using the snap store (app center) , then go and delete the .gem folder , you'll find the .gem folder in the home folder and it's hidden by default&lt;/p&gt;

&lt;p&gt;you should have ruby uninstalled and deleted .gems folder &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1.1 : Installing Ruby&lt;/strong&gt; 🙂&lt;/p&gt;

&lt;p&gt;Install ruby &lt;br&gt;
There is two ways to install it &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;using snap store (app center)&lt;/li&gt;
&lt;li&gt;using the terminal
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;snap intall ruby &lt;span class="nt"&gt;--classic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;--classic&lt;/code&gt; flag is used because Ruby requires classic confinement to access certain system resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Verify the Installation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After the installation is complete, you can verify that Ruby is installed correctly by checking its version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ruby &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Set Up the PATH&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;You need to add the Snap binary directory to your PATH. I don't what is this but you can do it by editing your &lt;code&gt;.bashrc&lt;/code&gt; file.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your &lt;code&gt;.bashrc&lt;/code&gt; in a text editor
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gnome-text-editor ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add the following line at the end of the txt file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;:/snap/bin"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;:/path/to/gem/bin"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;/path/to/gem/bin&lt;/code&gt; with your path . &lt;br&gt;
It should look like something like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;:/home/ali/.gem/bin"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;:/home/your_username/.gem/ruby/3.x.x/bin"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make sure what is your path , check the gem path using this command in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will list a long list of things about &lt;strong&gt;RubyGems Environment&lt;/strong&gt; , we need the  &lt;code&gt;- EXECUTABLE DIRECTORY:&lt;/code&gt; path line  .&lt;/p&gt;

&lt;p&gt;Now save your changes and reload your shell config using :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when you download any new gem , it will work automatically , try installing Rspec and test it in both VSCode and Terminal &lt;/p&gt;

&lt;p&gt;The reason why I  told you to delete the old .gem folder is becasue no one wants to manually edit the shebang line , I don't know what is a shebang but that's what ChatGPT told me .&lt;/p&gt;

&lt;p&gt;That's it &lt;/p&gt;

&lt;p&gt;See you later &lt;/p&gt;

</description>
      <category>ruby</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
