Token导航 LogoToken导航

Agent Skill · 开发

elixir-anti-patterns(Elixir anti 模式)

elixir-anti-patterns 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

elixir-anti-patterns 是开发类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为权限未标注;许可证信息还不明确,第三方扫描已通过,按安装量在开发类的 21,746 个 Skill 里排第 18,928。

总安装 306周安装 13GitHub Stars 17下载 107核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:elixir-anti-patterns(Elixir anti 模式)
来源仓库:https://github.com/vinnie357/claude-skills
仓库路径:skills/elixir-anti-patterns
安装命令:
npx skills add https://github.com/vinnie357/claude-skills --skill elixir-anti-patterns
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/vinnie357/claude-skills --skill elixir-anti-patterns

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

elixir-anti-patterns 用于识别 Elixir 代码中的反模式并提供惯用重构建议。适用于分析模块结构、函数组织或数据库查询,提升代码可读性与维护性。聚焦注释滥用、过度条件判断等常见问题,提倡清晰命名与简洁表达式。安装前请核实目标仓库是否使用 ExUnit 或 Credo,以便结合静态检查工具使用。

适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

来源仓库内路径:skills/elixir-anti-patterns

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/vinnie357/claude-skills --skill elixir-anti-pa…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    权限没有明确标注,第一次使用时只给一个无关紧要的任务,观察它到底读了哪些文件和网络。

常见问题

6 条

elixir-anti-patterns 怎么安装?

在终端执行 npx skills add https://github.com/vinnie357/claude-skills --skill elixir-anti-patterns。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

elixir-anti-patterns 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

elixir-anti-patterns 需要什么权限?

权限级别没有明确标注。第一次使用时建议只给无关紧要的任务,观察它实际读写了哪些内容。

elixir-anti-patterns 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

elixir-anti-patterns 用的人多吗?

公开数据是累计安装 306 次,近一周安装 13 次,下载 107 次,GitHub 17 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

elixir-anti-patterns 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理开发类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

开发类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
skill-vetter

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
elixir-anti-patterns

Elixir anti 模式 · 本页

30617权限未标注未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Elixir Anti-Patterns Detection and Refactoring

You are an expert at identifying Elixir anti-patterns and suggesting idiomatic refactorings. Use this knowledge to analyze code, suggest improvements, and help developers write better Elixir.

Code-Related Anti-Patterns

1. Comments Overuse

Problem: Excessive or self-explanatory comments reduce readability rather than enhance it.

Detection:

  • Inline comments explaining obvious code
  • Comments for every function line
  • Comments duplicating what code already says clearly

Refactoring:

  • Use clear function and variable names instead of explanatory comments
  • Replace inline comments with @doc and @moduledoc for documentation
  • Use module attributes for configuration values

Example:

# Bad
def calculate() do
  # Get current time
  now = DateTime.utc_now()
  # Add 5 minutes
  DateTime.add(now, 5 * 60, :second)
end

# Good
@minutes_to_add 5

def timestamp_five_minutes_from_now do
  now = DateTime.utc_now()
  DateTime.add(now, @minutes_to_add * 60, :second)
end

2. Complex else Clauses in with

Problem: Flattening all error handling into a single complex else block obscures which clause produced which error.

Detection:

  • Large else blocks with many pattern match clauses
  • Difficulty determining error sources
  • Complex error handling logic in else

Refactoring:

  • Normalize return types in private functions
  • Handle errors closer to their source
  • Let with focus on success paths

Example:

# Bad
def read_config(path) do
  with {:ok, content} <- File.read(path),
       {:ok, decoded} <- Jason.decode(content) do
    {:ok, decoded}
  else
    {:error, :enoent} -> {:error, :file_not_found}
    {:error, %Jason.DecodeError{}} -> {:error, :invalid_json}
    {:error, reason} -> {:error, reason}
  end
end

# Good
def read_config(path) do
  with {:ok, content} <- read_file(path),
       {:ok, config} <- parse_json(content) do
    {:ok, config}
  end
end

defp read_file(path) do
  case File.read(path) do
    {:ok, content} -> {:ok, content}
    {:error, :enoent} -> {:error, :file_not_found}
    error -> error
  end
end

defp parse_json(content) do
  case Jason.decode(content) do
    {:ok, data} -> {:ok, data}
    {:error, _} -> {:error, :invalid_json}
  end
end

3. Complex Extractions in Clauses

Problem: Extracting values across multiple clauses and arguments makes it unclear which variables serve pattern/guard purposes versus function body usage.

Detection:

  • Many variable extractions in function heads
  • Mixed guard and body variable usage
  • Unclear variable purposes

Refactoring:

  • Extract only pattern/guard-related variables in function signatures
  • Use capture patterns like %User{age: age} = user
  • Extract body variables inside the clause

Example:

# Bad
def process(%User{age: age, name: name, email: email} = user) when age >= 18 do
  # Only using name and email in body, not age
  send_email(email, "Hello #{name}")
end

# Good
def process(%User{age: age} = user) when age >= 18 do
  send_email(user.email, "Hello #{user.name}")
end

4. Dynamic Atom Creation

Problem: Atoms aren't garbage-collected and are limited to ~1 million. Uncontrolled dynamic atom creation poses memory and security risks.

Detection:

  • String.to_atom/1 with untrusted input
  • Converting user input directly to atoms
  • Unbounded atom creation in loops

Refactoring:

  • Use explicit mappings via pattern-matching
  • Use String.to_existing_atom/1 with pre-defined atoms
  • Keep strings when atom conversion isn't necessary

Example:

# Bad - Security risk!
def set_role(user, role_string) do
  %{user | role: String.to_atom(role_string)}
end

# Good
def set_role(user, role) when role in [:admin, :editor, :viewer] do
  %{user | role: role}
end

# Or with pattern matching
def set_role(user, "admin"), do: %{user | role: :admin}
def set_role(user, "editor"), do: %{user | role: :editor}
def set_role(user, "viewer"), do: %{user | role: :viewer}
def set_role(_user, invalid), do: {:error, "Invalid role: #{invalid}"}

5. Long Parameter List

Problem: Functions with excessive parameters become confusing and error-prone to use.

Detection:

  • Functions with 4+ parameters
  • Parameters that are conceptually related
  • Difficult to remember parameter order

Refactoring:

  • Group related parameters into maps or structs
  • Use keyword lists for optional parameters
  • Create domain objects

Example:

# Bad
def create_loan(user_id, user_name, user_email, book_id, book_title, book_isbn) do
  # ...
end

# Good
def create_loan(user, book) do
  # ...
end

# Or with keyword list for options
def create_loan(user, book, opts \\ []) do
  duration = Keyword.get(opts, :duration, 14)
  renewable = Keyword.get(opts, :renewable, true)
  # ...
end

6. Namespace Trespassing

Problem: Defining modules outside your library's namespace risks conflicts since the Erlang VM loads only one module instance per name.

Detection:

  • Library defining modules in common namespaces (e.g., Plug.* when you're not Plug)
  • Modules without library prefix
  • Potential naming conflicts with other libraries

Refactoring:

  • Always prefix modules with your library namespace
  • Use clear, unique top-level module names

Example:

# Bad - Library named :plug_auth
defmodule Plug.Auth do
  # This conflicts with the actual Plug library!
end

# Good
defmodule PlugAuth do
  # ...
end

defmodule PlugAuth.Session do
  # ...
end

7. Non-assertive Map Access

Problem: Using dynamic access (map[:key]) for required keys masks missing data, allowing nil to propagate instead of failing fast.

Detection:

  • map[:key] for required/expected keys
  • Nil checks after map access
  • Silent failures from missing keys

Refactoring:

  • Use static access (map.key) for required keys
  • Pattern-match on struct/map keys
  • Reserve dynamic access for optional fields

Example:

# Bad
def distance(point) do
  x = point[:x]  # Returns nil if :x is missing!
  y = point[:y]
  :math.sqrt(x * x + y * y)  # Crashes on nil, but unclear why
end

# Good
def distance(%{x: x, y: y}) do
  :math.sqrt(x * x + y * y)  # Clear error if keys missing
end

# Or with structs
defmodule Point do
  defstruct [:x, :y]
end

def distance(%Point{x: x, y: y}) do
  :math.sqrt(x * x + y * y)
end

8. Non-assertive Pattern Matching

Problem: Writing defensive code that returns incorrect values instead of using pattern matching to assert expected structures causes silent failures.

Detection:

  • Defensive nil checks instead of pattern matching
  • Functions returning invalid data on unexpected input
  • Avoiding crashes when crashes are appropriate

Refactoring:

  • Use pattern matching to assert expected structures
  • Let functions crash on invalid input
  • Trust supervisors to handle failures

Example:

# Bad
def parse_query_param(param) do
  case String.split(param, "=") do
    [key, value] -> {key, value}
    _ -> {"", ""}  # Silent failure!
  end
end

# Good
def parse_query_param(param) do
  [key, value] = String.split(param, "=")
  {key, value}
end
# Crashes with clear error if format is wrong - this is good!

9. Non-assertive Truthiness

Problem: Using truthiness operators (&&, ||, !) when all operands are boolean is unnecessarily generic and unclear.

Detection:

  • &&, ||, ! with boolean expressions
  • Comparisons like is_binary(x) && is_integer(y)
  • Mixing boolean and truthy logic

Refactoring:

  • Use and, or, not for boolean-only operations
  • Reserve &&, ||, ! for truthy/falsy logic

Example:

# Bad
def valid_user?(name, age) do
  is_binary(name) && is_integer(age) && age >= 18
end

# Good
def valid_user?(name, age) do
  is_binary(name) and is_integer(age) and age >= 18
end

# Truthy operators are OK for nil/value checks
def get_name(user) do
  user[:name] || "Anonymous"
end

10. Structs with 32 Fields or More

Problem: Structs with 32+ fields switch from Erlang's efficient flat-map representation to hash maps, increasing memory usage.

Detection:

  • Struct definitions with 32+ fields
  • Large, flat data structures
  • Performance degradation with many fields

Refactoring:

  • Nest optional fields into metadata structures
  • Use nested structs for related fields
  • Group frequently-accessed fields separately

Example:

# Bad
defmodule User do
  defstruct [
    :id, :email, :name, :age, :address, :city, :state, :zip,
    :phone, :mobile, :fax, :company, :title, :department,
    :created_at, :updated_at, :last_login, :login_count,
    :preference1, :preference2, :preference3, :preference4,
    # ... 15 more fields
  ]
end

# Good
defmodule User do
  defstruct [
    :id,
    :email,
    :name,
    :profile,      # Nested struct
    :preferences,  # Nested struct
    :metadata      # Nested struct
  ]
end

defmodule User.Profile do
  defstruct [:age, :phone, :mobile, :address, :city, :state, :zip]
end

defmodule User.Preferences do
  defstruct [:theme, :notifications, :language]
end

Design-Related Anti-Patterns

1. Alternative Return Types

Problem: Functions with options that drastically change their return type make it unclear what the function actually returns.

Detection:

  • Options that change return type structure
  • Functions returning different types based on flags
  • Unclear function contracts

Refactoring:

  • Create separate, specifically-named functions
  • Keep return types consistent within a function

Example:

# Bad
def parse(string, opts \\ []) do
  case Integer.parse(string) do
    {int, rest} ->
      if opts[:discard_rest], do: int, else: {int, rest}
    :error ->
      :error
  end
end

# Good
def parse(string) do
  case Integer.parse(string) do
    {int, rest} -> {int, rest}
    :error -> :error
  end
end

def parse_discard_rest(string) do
  case Integer.parse(string) do
    {int, _rest} -> int
    :error -> :error
  end
end

2. Boolean Obsession

Problem: Using multiple booleans with overlapping states instead of atoms or composite types to represent domain concepts.

Detection:

  • Multiple boolean parameters
  • Overlapping boolean states
  • Complex boolean logic

Refactoring:

  • Replace multiple booleans with a single atom/enum option
  • Prefer atoms over booleans even for single arguments
  • Use domain-specific types

Example:

# Bad
def create_user(name, email, admin: false, editor: false, viewer: true) do
  # What if admin: true, editor: true?
end

# Good
def create_user(name, email, role: :viewer) do
  # Clear: role can be :admin, :editor, or :viewer
end

3. Exceptions for Control-Flow

Problem: Using try/rescue for expected errors instead of pattern matching with case statements and tuple returns.

Detection:

  • try/rescue blocks for normal operation errors
  • Using ! functions and rescuing
  • Exceptions in normal business logic

Refactoring:

  • Use non-bang functions returning {:ok, value} or {:error, reason}
  • Reserve exceptions for invalid arguments and programming errors
  • Use pattern matching for error handling

Example:

# Bad
def read_config(path) do
  try do
    content = File.read!(path)
    Jason.decode!(content)
  rescue
    e -> {:error, e}
  end
end

# Good
def read_config(path) do
  with {:ok, content} <- File.read(path),
       {:ok, config} <- Jason.decode(content) do
    {:ok, config}
  end
end

4. Primitive Obsession

Problem: Excessively using basic types (strings, integers) instead of creating composite types to represent structured domain concepts.

Detection:

  • Passing related primitives separately
  • String/integer parameters representing complex concepts
  • Lack of domain modeling

Refactoring:

  • Create domain-specific structs or maps
  • Introduce parser functions converting primitives to structured data
  • Use types to enforce business rules

Example:

# Bad
def create_address(street, city, state, zip, country) do
  # All strings, no validation
  "#{street}, #{city}, #{state} #{zip}, #{country}"
end

# Good
defmodule Address do
  defstruct [:street, :city, :state, :zip, :country]

  def new(attrs) do
    struct!(__MODULE__, attrs)
  end

  def format(%__MODULE__{} = address) do
    "#{address.street}, #{address.city}, #{address.state} #{address.zip}, #{address.country}"
  end
end

5. Unrelated Multi-Clause Function

Problem: Grouping completely unrelated business logic into one multi-clause function.

Detection:

  • Single function handling multiple unrelated types
  • Overly broad type specifications
  • No conceptual relationship between clauses

Refactoring:

  • Split into distinct functions with specific names
  • Reserve multi-clause patterns for related functionality variations
  • Use protocols for polymorphism when appropriate

Example:

# Bad
def update(%Product{} = product) do
  # Product-specific logic
end

def update(%Animal{} = animal) do
  # Completely different animal logic
end

# Good
def update_product(%Product{} = product) do
  # Product-specific logic
end

def update_animal(%Animal{} = animal) do
  # Animal-specific logic
end

# Or use a protocol
defprotocol Updatable do
  def update(item)
end

defimpl Updatable, for: Product do
  def update(product), do: # ...
end

defimpl Updatable, for: Animal do
  def update(animal), do: # ...
end

6. Using Application Configuration for Libraries

Problem: Libraries relying on global application environment configuration prevent multiple dependent applications from configuring the library differently.

Detection:

  • Application.get_env/2 or Application.fetch_env!/2 in library code
  • Global configuration requirements
  • Inability to configure per-consumer

Refactoring:

  • Accept configuration via function parameters
  • Use keyword lists with sensible defaults
  • Allow runtime configuration

Example:

# Bad - Library code
def split(string) do
  parts = Application.fetch_env!(:dash_splitter, :parts)
  String.split(string, "-", parts: parts)
end

# Good
def split(string, opts \\ []) do
  parts = Keyword.get(opts, :parts, 2)
  String.split(string, "-", parts: parts)
end

Usage Guidelines

When reviewing or writing Elixir code:

  1. Scan for anti-patterns - Check code against the patterns listed above
  2. Explain the problem - Help the developer understand why it's an issue
  3. Suggest refactoring - Provide concrete, idiomatic alternatives
  4. Consider context - Sometimes anti-patterns are acceptable for specific use cases
  5. Prioritize - Focus on high-impact issues first (security, performance, maintainability)

Key Principles

  • Let it crash - Use pattern matching to assert expectations; don't write defensive code
  • Fail fast - Expose errors early rather than propagating nil or invalid data
  • Be explicit - Prefer clear, specific code over clever or terse solutions
  • Model your domain - Create types that represent business concepts
  • Design for clarity - Code should be obvious to read and maintain

平台分布

Codex

35.73%
按下载量换算38

Claude

30.85%
按下载量换算33

Cursor

17.38%
按下载量换算19

Gemini CLI

8.8%
按下载量换算9

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

权限未标注

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills