Przejdź do treści
Biblioteka skilli
Programowanie · Budowanie i kod

elixir-expert

/elixir-expert

Wspiera pracę z Elixirem, Phoenix, OTP i systemami współbieżnymi.

Repozytorium
pcl ↗
Licencja
Apache-2.0
Ostatnia zmiana repozytorium
10.09.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
2
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
4
Przestarzałość

Brak sygnałów. Repozytorium zmienione 10.09.2026, bez odwołań do wycofanych modeli i API.

Licencja

Apache-2.0, otwarta: można używać i zmieniać, z zachowaniem licencji i informacji o zmianach.

Co robi i kiedy

Wspiera pracę z Elixirem, Phoenix, OTP i systemami współbieżnymi.

Oryginalny opis (EN)

Expert-level Elixir, Phoenix, OTP, and concurrent systems. Use when the user mentions Phoenix, OTP, Erlang, concurrent, or functional, or when the task involves Elixir Fundamentals or Phoenix Framework.

Jak działa

  1. Core Concepts
  2. Elixir Basics
  3. GenServer
  4. Supervisors
  5. Ecto
  6. Phoenix LiveView
  7. Concurrency
  8. Best Practices
  9. Anti-Patterns
  10. Reference Documentation
Sekcje z nagłówków SKILL.md, w oryginale · 430 linii, 1 022 słów
Podgląd SKILL.md
---
name: elixir-expert
version: 1.1.0
description: >-
  Expert-level Elixir, Phoenix, OTP, and concurrent systems. Use when the user mentions
  Phoenix, OTP, Erlang, concurrent, or functional, or when the task involves Elixir
  Fundamentals or Phoenix Framework.
category: languages
tags: [elixir, phoenix, otp, erlang, concurrent, functional]
allowed-tools:
  - Read
  - Write
  - Edit
  - Bash(elixir:*, mix:*)
---

# Elixir Expert

Expert guidance for Elixir programming, Phoenix framework, OTP, and building highly concurrent, fault-tolerant systems.

## Core Concepts

### Elixir Fundamentals

- Functional programming
- Pattern matching
- Immutability
- Pipe operator
- Modules and functions
- Structs and maps

### OTP (Open Telecom Platform)

- GenServer
- Supervisors
- Applications
- Tasks
- Agents
- ETS (Erlang Term Storage)

### Phoenix Framework

- Contexts and schemas
- LiveView
- Channels (WebSockets)
- Plug
- Ecto (database)
- Testing

## Elixir Basics

```elixir
# Pattern matching
{:ok, result} = {:ok, 42}
[head | tail] = [1, 2, 3, 4]

# Functions
defmodule Math do
  def add(a, b), do: a + b

  def factorial(0), do: 1
  def factorial(n) when n > 0, do: n * factorial(n - 1)
end

# Pipe operator
"hello"
|> String.upcase()
|> String.reverse()
# "OLLEH"

# Anonymous functions
add = fn a, b -> a + b end
add.(1, 2)  # 3

# Capture operator
add = &(&1 + &2)
Enum.map([1, 2, 3], &(&1 * 2))

# Structs
defmodule User do
  defstruct [:id, :name, :email, age: 0]
end

user = %User{id: "123", name: "John", email: "john@example.com"}

# Pattern matching with structs
%User{name: name} = user

# Maps
user_map = %{id: "123", name: "John", email: "john@example.com"}
%{name: name} = user_map

# Conditionals
if user.age >= 18 do
  "Adult"
else
  "Minor"
end

# Case
case user.role do
  :admin -> "Administrator"
  :user -> "Regular user"
  _ -> "Unknown"
end

# Cond
cond do
  user.age < 13 -> "Child"
  user.age < 18 -> "Teen"
  user.age < 65 -> "Adult"
  true -> "Senior"
end

# With
with {:ok, user} <- fetch_user(id),
     {:ok, posts} <- fetch_posts(user.id) do
  {:ok, user, posts}
else
  {:error, reason} -> {:error, reason}
end
```

## GenServer

```elixir
defmodule UserCache do
  use GenServer

  # Client API
  def start_link(opts \\ []) do
    GenServer.start_link(__MODULE__, %{}, opts)
  end

  def get(server, key) do
    GenServer.call(server, {:get, key})
  end

  def put(server, key, value) do
    GenServer.cast(server, {:put, key, value})
  end

  # Server Callbacks
  @impl true
  def init(initial_state) do
    {:ok, initial_state}
  end

  @impl true
  def handle_call({:get, key}, _from, state) do
    {:reply, Map.get(state, key), state}
  end

  @impl true
  def handle_cast({:put, key, value}, state) do
    {:noreply, Map.put(state, key, value)}
  end

  @impl true
  def handle_info(:cleanup, state) do
    # Periodic cleanup
    {:noreply, state}
  end
end

# Usage
{:ok, cache} = UserCache.start_link()
UserCache.put(cache, :user1, %User{name: "John"})
UserCache.get(cache, :user1)
```

## Supervisors

```elixir
defmodule MyApp.Application do
  use Application

  @impl true
  def start(_type, _args) do
    children = [
      # Database connection pool
      {MyApp.Repo, []},

      # GenServer workers
      {UserCache, name: UserCache},
      {SessionManager, name: SessionManager},

      # Task supervisor
      {Task.Supervisor, name: MyApp.TaskSupervisor},

      # Phoenix endpoint
      MyAppWeb.Endpoint
    ]

    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

# Custom supervisor
defmodule WorkerSupervisor do
  use Supervisor

  def start_link(init_arg) do
    Supervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
  end

  @impl true
  def init(_init_arg) do
    children = [
      {Worker, id: :worker1, restart: :permanent},
      {Worker, id: :worker2, restart: :temporary},
      {Worker, id: :worker3, restart: :transient}
    ]

    Supervisor.init(children, strategy: :one_for_one)
  end
end
```

## Ecto

```elixir
# Schema
defmodule MyApp.Accounts.User do
  use Ecto.Schema
  import Ecto.Changeset

  schema "users" do
    field :name, :string
    field :email, :string
    field :age, :integer
    field :role, Ecto.Enum, values: [:admin, :user, :guest]

    has_many :posts, MyApp.Blog.Post

    timestamps()
  end

  def changeset(user, attrs) do
    user
    |> cast(attrs, [:name, :email, :age, :role])
    |> validate_required([:name, :email])
    |> validate_format(:email, ~r/@/)
    |> validate_number(:age, greater_than: 0, less_than: 150)
    |> unique_constraint(:email)
  end
end

# Queries
import Ecto.Query

# Simple query
Repo.all(from u in User, where: u.age > 18)

# With preload
Repo.all(from u in User, preload: [:posts])

# Complex query
query =
  from u in User,
    join: p in assoc(u, :posts),
    where: u.age > 18,
    group_by: u.id,
    having: count(p.id) > 5,
    select: {u, count(p.id)}

Repo.all(query)

# Dynamic queries
defmodule UserQueries do
  import Ecto.Query

  def base_query, do: from(u in User)

  def filter_by_age(query, min_age) do
    from u in query, where: u.age >= ^min_age
  end

  def filter_by_role(query, role) do
    from u in query, where: u.role == ^role
  end

  def with_posts(query) do
    from u in query, preload: [:posts]
  end
end

# Usage
User
|> UserQueries.base_query()
|> UserQueries.filter_by_age(18)
|> UserQueries.filter_by_role(:admin)
|> UserQueries.with_posts()
|> Repo.all()
```

## Phoenix LiveView

```elixir
defmodule MyAppWeb.UserLive.Index do
  use MyAppWeb, :live_view

  alias MyApp.Accounts

  @impl true
  def mount(_params, _session, socket) do
    if connected?(socket) do
      Phoenix.PubSub.subscribe(MyApp.PubSub, "users")
    end

    {:ok, assign(socket, users: Accounts.list_users())}
  end

  @impl true
  def handle_event("delete", %{"id" => id}, socket) do
    user = Accounts.get_user!(id)
    {:ok, _} = Accounts.delete_user(user)

    {:noreply, assign(socket, users: Accounts.list_users())}
  end

  @impl true
  def handle_info({:user_created, user}, socket) do
    {:noreply, update(socket, :users, fn users -> [user | users] end)}
  end

  @impl true
  def render(assigns) do
    ~H"""
    <div>
      <h1>Users</h1>
      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody>
          <%= for user <- @users do %>
            <tr>
              <td><%= user.name %></td>
              <td><%= user.email %></td>
              <td>
                <button phx-click="delete" phx-value-id={user.id}>
                  Delete
                </button>
              </td>
            </tr>
          <% end %>
        </tbody>
      </table>
    </div>
    """
  end
end
```

## Concurrency

```elixir
# Tasks
task = Task.async(fn -> expensive_computation() end)
result = Task.await(task)

# Parallel processing
results =
  [1, 2, 3, 4, 5]
  |> Enum.map(&Task.async(fn -> process(&1) end))
  |> Enum.map(&Task.await/1)

# Task supervisor
Task.Supervisor.async_nolink(MyApp.TaskSupervisor, fn ->
  perform_background_job()
end)

# Agents
{:ok, agent} = Agent.start_link(fn -> %{} end)
Agent.update(agent, fn state -> Map.put(state, :key, "value") end)
Agent.get(agent, fn state -> Map.get(state, :key) end)

# ETS
table = :ets.new(:my_table, [:set, :public])
:ets.insert(table, {:key, "value"})
:ets.lookup(table, :key)
```

## Best Practices

### Elixir

- Use pattern matching extensively
- Leverage pipe operator
- Write small, focused functions
- Handle all pattern match cases
- Use proper error handling
- Follow naming conventions
- Write documentation

### OTP

- Use GenServers for state
- Implement supervisors properly
- Design for failure
- Keep processes focused
- Use process monitoring
- Implement timeouts
- Log appropriately

### Phoenix

- Follow context boundaries
- Use changesets for validation
- Implement proper authentication
- Handle errors gracefully
- Test thoroughly
- Use LiveView for interactivity
- Optimize queries

## Anti-Patterns

❌ Using mutable state
❌ Long-running GenServer calls
❌ Not supervising processes
❌ Ignoring errors
❌ Large modules
❌ N+1 query problems
❌ Not using pattern matching

## Reference Documentation

Detailed material lives alongside this skill and is read on demand:

- [Phoenix Framework](references/PHOENIX_FRAMEWORK.md)

## Resources

- Elixir: https://elixir-lang.org/
- Phoenix: https://www.phoenixframework.org/
- Hex: https://hex.pm/
- Elixir School: https://elixirschool.com/
- Programming Elixir (book)
Pliki w paczce (2)
  • SKILL.md 8 KB
  • references/PHOENIX_FRAMEWORK.md 2 KB

Wersje

RepozytoriumWynikLicencja
Ta strona · personamanagmentlayer/pcl100Apache-2.0
agentic-swe/agentic-swe100MIT

Migawka bazy z 13.11.2026 · wersja paczki f223bea3d7dc (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 95elixir
    Odpowiada na pytania o narzędzia Elixira: Mix, OTP, Phoenix, Ecto, współbieżność, testy i wdrożenia produkcyjne.
  • 100elixir
    Wspiera programowanie w Elixirze: dopasowanie wzorców, GenServer, supervisory OTP i kanały Phoenix, dla współbieżnych, rozproszonych i odpornych na błędy systemów.
  • 95using-elixir-skills
    Kieruje pracę w Elixirze do właściwego skilla myślowego, zanim zacznie się eksplorowanie kodu w projektach Phoenix, Ecto i OTP.
  • 90elixir-pro
    Pisze idiomatyczny kod w Elixirze z wzorcami OTP, drzewami nadzoru i Phoenix LiveView oraz pomaga w optymalizacji BEAM.
  • 95elixir-otp-patterns
    Opisuje wzorce OTP w Elixirze (GenServer, Supervisor, Agent, Task) do budowy współbieżnych aplikacji odpornych na awarie.
  • 95elixir
    Pomaga budować aplikacje w Elixirze i Phoenix: zasady OTP, granice kontekstów, stan w LiveView i drzewa nadzoru.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.