Ne vous inquiétez pas, vous allez voir d'autres langages & framework

Qui je suis ?

Jonathan Boyer

  • Développeur fullstack
  • Principalement autodidacte
  • Freelance depuis 12 ans
  • Formateur /  Tutoriels vidéos sur grafikart.fr

C'est quoi le meilleur langage ?

Mon premier langage

package{
	
	import flash.display.MovieClip;
	import flash.display.Loader; 
	import flash.net.URLRequest;
    import flash.utils.Timer;
	import flash.events.Event;
    import flash.events.TimerEvent;
	import caurina.transitions.*;

	public class Diaporama extends MovieClip{
		
		var images;
		var compt:uint=0;
		var delai:Timer = new Timer(3000);
		
		public function Diaporama(list:Array):void{
			images=list;
			this.addChild(new MovieClip()); this.addChild(new MovieClip());
			delai.addEventListener(TimerEvent.TIMER,charger);
			charger();
		}
		
		private function charger(e=0){
			delai.stop();
			this.swapChildrenAt(0,1);
			this.removeChildAt(1);
			var l:Loader=new Loader();
			l.contentLoaderInfo.addEventListener(Event.COMPLETE,appar);
			l.load(new URLRequest(images[compt]));
			this.addChildAt(l,1);
			compt++;
			if(compt>=images.length){
				compt=0;
			}
		}
		private function appar(e:Event){
			this.getChildAt(1).alpha=0;
			this.getChildAt(1).x=this.getChildAt(1).y=-200;
			Tweener.addTween(this.getChildAt(1),{x:-200+(Math.round(Math.random()*2)-1)*100,y:-200+(Math.round(Math.random()*2)-1)*100, time:4, transition:"linear"});
			Tweener.addTween(this.getChildAt(1),{alpha:1, time:1, transition:"linear"});
			delai.start();
		}
	}
}

Un langage est un outil

et répond à un problème précis

« Si le seul outil que vous avez est un marteau, vous tendez à voir tout problème comme un clou »

Abraham Maslow (The Psychology of Science, 1966).

PHP

mais pour du temps réel :(

générer des pages HTML

Être développeur

= résoudre des problèmes

Apprendre un nouveau langage

oublier le langage précédent

Améliore ses compétences globales

Pourquoi apprendre un nouveau langage ?

Elixir

defmodule Discordbot.Commands.SMS do
  @moduledoc """
  Permet aux utilisateur d'alerter l'administrateur par SMS en cas de problème
  Utilise l'API de Free
  """

  alias DiscordEx.RestClient.Resources.Channel
  alias DiscordEx.RestClient.Resources.Guild

  @doc """
  Send a message on general channel
  """
  def handle(:message_create, payload = %{"content" => "!sms " <> _message}, state = %{rest_client: conn}) do
    Channel.delete_message(conn, payload["channel_id"], payload["id"])
    handle_sms(payload, state, __MODULE__)
  end

  def handle(_type, _data, state) do
    {:no, state}
  end

  def handle_sms(payload = %{"content" => "!sms " <> message}, state = %{rest_client: conn}, module) do
    if module.is_allowed(conn, payload) && !is_within_hour?(Map.get(state, :last_sms)) do
      module.send(message)
      {:ok, Map.put(state, :last_sms, :os.system_time(:seconds))}
    else
      {:no, state}
    end
  end

  defp is_within_hour?(nil) do false end
  defp is_within_hour?(time) do
    :os.system_time(:seconds) - time <= 3600
  end

  @doc """
  Send an SMS using mobile.free.fr
  """
  def send(message) do
    credentials = :discordbot |> Application.get_env(:sms) |> Keyword.get(:credentials)
    HTTPoison.get("https://smsapi.free-mobile.fr/sendmsg", [], [params: Keyword.put(credentials, :msg, message)])
  end

  @doc """
  Does the user belongs to a role that can send SMS alerts ?
  """
  def is_allowed(conn, payload) do
    expected_role = :discordbot
      |> Application.get_env(:sms)
      |> Keyword.get(:role)
    %{"guild_id" => guild_id} = Channel.get(conn, payload["channel_id"])
    %{"roles" => roles} = Guild.member(conn, guild_id, payload["author"]["id"])
    Enum.member?(roles, expected_role)
  end

end
  • La programmation fonctionnelle
    (map, reduce & filter)

  • Fonction pure

  • Immutabilité

Ce que j'ai appris

Affine ses préférences

Pourquoi apprendre un nouveau langage ?

Ruby & Ruby on Rails

class PetsController < ApplicationController

  before_action :set_pet, only: [:edit, :update, :destroy]
  skip_before_action :only_signed_in, only: [:show]

  def show
    @pet = Pet.find(params[:id])
  end

  def index
    @pets = current_user.pets
  end

  def new
    @pet = current_user.pets.new
  end

  def create
    @pet = current_user.pets.new(pet_params)
    if @pet.save
      redirect_to pets_path, success: 'Votre animal a bien été créé'
    else
      render :new
    end
  end

  def edit
  end

  def update
    if @pet.update(pet_params)
      redirect_to pets_path, success: 'Votre animal a bien été modifié'
    else
      render :edit
    end
  end

  def destroy
    @pet.destroy
    redirect_to pets_path, success: 'Votre animal a bien été supprimé'
  end

  private

  def pet_params
    params.require(:pet).permit(:name, :gender, :birthday, :species_id, :avatar_file)
  end

  def set_pet
    @pet = current_user.pets.find(params[:id])
  end

end
tomorrow = 1.days.from_now
class Integer
  
  def days
    # ....
  end
  
end

Je n'aime pas la magie :(

Ce que j'ai appris

module ImageConcern

  extend ActiveSupport::Concern

  module ClassMethods

    def has_image(field, options = {})
      options[:resize] = '150x150!' if options[:resize].nil?

      attr_accessor "#{field}_file".to_sym
      validates "#{field}_file".to_sym, file: {ext: [:jpg, :png]}
      after_save "#{field}_after_upload".to_sym
      before_save "#{field}_before_upload".to_sym
      after_destroy_commit "#{field}_destroy".to_sym

      class_eval <<-METHODS, __FILE__, __LINE__ + 1
        def #{field}_url(format = nil)
          format = "_\#{format}" unless format.nil?
          '/uploads/' + [
            self.class.name.downcase.pluralize,
            id.to_s,
            "#{field}\#{format}.jpg"
          ].join('/')
        end

        def #{field}_path
          File.join(
            Rails.public_path,
            'uploads',
            self.class.name.downcase.pluralize,
            id.to_s,
            '#{field}.jpg'
          )
        end

        private
      
        def #{field}_before_upload
          if #{field}_file.respond_to?(:path) and self.respond_to?(:#{field})
            self.#{field} = true
          end
        end
      
        def #{field}_after_upload
          path = #{field}_path
          options = #{options}
          if #{field}_file.respond_to? :path
            dir = File.dirname(path)
            FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
            image = MiniMagick::Image.new(#{field}_file.path) do |b|
              if options[:resize].ends_with?('!') 
                b.resize '#{options[:resize].delete('!')}^'
                b.gravity 'Center'
                b.crop '#{options[:resize].delete('!')}+0+0'
              else
                b.resize '#{options[:resize].delete('!')}\>'
              end
            end
            image.format 'jpg'
            image.write path
            if options[:formats]
              options[:formats].each do |k, v|
                image = MiniMagick::Image.new(#{field}_file.path) do |b|
                  b.resize "\#{v}^"
                  b.gravity 'Center'
                  b.crop "\#{v}+0+0"
                end
                image.format 'jpg'
                image.write path.gsub('.jpg', "_\#{k}.jpg")
              end
            end
          end
        end
      
        def #{field}_destroy
          dir = File.dirname(#{field}_path)
          FileUtils.rm_r(dir) if Dir.exist?(dir)
        end
      METHODS
    end

  end

end
class Post
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ORM\Column(type="integer")
     */
    private ?int $id = null;

    private string $type = '';

    /**
     * @ORM\Column(type="string", length=255)
     */
    private ?string $title = null;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private ?string $slug = null;

    /**
     * @ORM\Column(type="text")
     */
    private ?string $content = null;

    /**
     * @ORM\Column(type="datetime")
     */
    private ?\DateTimeInterface $createdAt = null;

    /**
     * @ORM\Column(type="datetime")
     */
    private ?\DateTimeInterface $updated_at = null;

    /**
     * @ORM\Column(type="boolean", options={"default": 0})
     */
    private bool $online = false;

    /**
     * @ORM\ManyToOne(targetEntity="App\Domain\Attachment\Attachment", cascade={"persist"})
     * @ORM\JoinColumn(name="attachment_id", referencedColumnName="id")
     */
    private ?Attachment $image = null;

    /**
     * @ORM\ManyToOne(targetEntity="App\Domain\Auth\User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private ?User $author = null;

    /**
     * @ORM\OneToMany(targetEntity="App\Domain\Course\Entity\TechnologyUsage", mappedBy="content", cascade={"persist"})
     *
     * @var Collection<int, TechnologyUsage>
     */
    private Collection $technologyUsages;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getTitle(): ?string
    {
        return $this->title;
    }

    /**
     * @param string $title
     *
     * @return $this
     */
    public function setTitle(?string $title): self
    {
        $this->title = $title;

        return $this;
    }

  
 }
class Post extends Eloquent
{
  
}

Laravel

Symfony

$post = Post::find(12);
$post->title // "Hello World"

Vous n'êtes pas obligé de maitriser

Connaitre les forces / faiblesses suffit

C'est quoi le meilleur langage ?

Par quel langage je devrais commencer ?

C'est quoi le meilleur langage ?

Conclusion

  • Commencez et pratiquez !
  • Focalisez vous sur vos connaissances (plus que les langages)
  • Soyez ouvert d'esprit !
  • Les langages sont un moyen, pas une fin

Questions ?

Pourquoi apprendre plusieurs languages

By Jonathan Boyer

Pourquoi apprendre plusieurs languages

  • 1,113