{"id":15056409,"url":"https://github.com/rabbitmq/horus","last_synced_at":"2025-04-05T23:06:33.013Z","repository":{"id":148558512,"uuid":"615002002","full_name":"rabbitmq/horus","owner":"rabbitmq","description":"Erlang library to create standalone modules from anonymous functions","archived":false,"fork":false,"pushed_at":"2025-02-28T14:36:49.000Z","size":585,"stargazers_count":28,"open_issues_count":3,"forks_count":1,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-03-29T22:05:49.372Z","etag":null,"topics":["assembly","elixir","elixir-library","erlang","erlang-library"],"latest_commit_sha":null,"homepage":"https://rabbitmq.github.io/horus/","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rabbitmq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-Apache-2.0","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-16T18:47:13.000Z","updated_at":"2025-01-21T09:30:10.000Z","dependencies_parsed_at":"2023-11-22T16:15:57.873Z","dependency_job_id":"87c58116-d8fe-4ba0-8115-dd6eae32e240","html_url":"https://github.com/rabbitmq/horus","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabbitmq%2Fhorus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabbitmq%2Fhorus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabbitmq%2Fhorus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabbitmq%2Fhorus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rabbitmq","download_url":"https://codeload.github.com/rabbitmq/horus/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247411229,"owners_count":20934653,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assembly","elixir","elixir-library","erlang","erlang-library"],"created_at":"2024-09-24T21:50:58.725Z","updated_at":"2025-04-05T23:06:32.996Z","avatar_url":"https://github.com/rabbitmq.png","language":"Erlang","readme":"# Horus: anonymous function to standalone module\n\n[![Hex.pm](https://img.shields.io/hexpm/v/horus)](https://hex.pm/packages/horus/)\n[![Test](https://github.com/rabbitmq/horus/actions/workflows/test-and-release.yaml/badge.svg)](https://github.com/rabbitmq/horus/actions/workflows/test-and-release.yaml)\n[![Codecov](https://codecov.io/gh/rabbitmq/horus/branch/main/graph/badge.svg?token=R0OGKZ2RK2)](https://codecov.io/gh/rabbitmq/horus)\n\nHorus is a library that extracts an anonymous function's code as well as the\ncode of the all the functions it calls, and creates a standalone version of it\nin a new module at runtime.\n\nThe goal is to have a storable and transferable function which does not depend\non the availability of the modules that defined it or were called.\n\n\u003cimg align=\"right\" height=\"150\" src=\"/doc/horus-logo.svg\"\u003e\n\n## How does it work?\n\nTo achieve that goal, Horus extracts the assembly code of the anonymous\nfunction, watches all calls it does and recursively extracts the assembly code\nof other called functions. When complete, it creates a standalone Erlang module\nbased on it. This module can be stored, transfered to another Erlang node and\nexecuted anywhere without the presence of the initial anonymous function's\nmodule.\n\nIf the extracted function calls directly or indirectly modules from the `erts`,\n`kernel` or `stdlib` applications, the called functions are not extracted.\nThat's ok because the behavior of Erlang/OTP modules rarely changes and they\nwill be available. Therefore, there is little value in extracting that code.\n\nWhile processing the assembly instructions and watching function calls, Horus\ncan use callbacks provided by the caller to determine if instructions and calls\nare allowed or denied.\n\n## Project maturity\n\nHorus is still under active development and should be considered *Alpha* at\nthis stage.\n\n## Documentation\n\n* A short tutorial in the [Getting started](#getting-started) section below\n* [Documentation and API reference](https://rabbitmq.github.io/horus/)\n\n## Getting started\n\n### Add as a dependency\n\nAdd Horus as a dependency of your project:\n\nUsing Rebar:\n\n```erlang\n%% In rebar.config\n{deps, [{horus, \"0.3.1\"}]}.\n```\n\nUsing Erlang.mk:\n\n```make\n# In your Makefile\nDEPS += horus\ndep_horus = hex 0.3.1\n```\n\nUsing Mix:\n\n```elixir\n# In mix.exs\ndefp deps do\n  [\n    {:horus, \"0.3.1\"}\n  ]\nend\n```\n\n### Extract an anonymous function\n\nTo extract an anonymous function, use `horus:to_standalone_fun/1`:\n\n```erlang\nFun = fun() -\u003e\n          do_something_fancy()\n      end,\n\nStandaloneFun = horus:to_standalone_fun(Fun).\n```\n\nIt works with references to regular functions are well:\n\n```erlang\nLog = fun logger:info/2,\n\nStandaloneLog = horus:to_standalone_fun(Log).\n```\n\n### Execute a standalone function\n\nOnce extracted, the function can be stored as an Erlang binary, or transfered\nto a remote Erlang node. You then use `horus:exec/2` to execute it:\n\n```erlang\nreceive\n    {standalone_fun, StandaloneLog} -\u003e\n        horus:exec(\n          StandaloneLog,\n          [\"~p received and executed function\", [self()]])\nend.\n```\n\n## How to build\n\n### Build\n\n```\nrebar3 compile\n```\n\n### Build documentation\n\n```\nrebar3 edoc\n```\n\n### Test\n\n```\nrebar3 xref\nrebar3 eunit\nrebar3 ct --sname ct\nrebar3 as test dialyzer\n```\n\n## Copyright and License\n\n© 2021-2025 Broadcom. All Rights Reserved. The term \"Broadcom\" refers to\nBroadcom Inc. and/or its subsidiaries.\n\nThis work is dual-licensed under the Apache License 2.0 and the Mozilla Public\nLicense 2.0. You can choose between one of them if you use this work.\n\nSPDX-License-Identifier: Apache-2.0 OR MPL-2.0\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frabbitmq%2Fhorus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frabbitmq%2Fhorus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frabbitmq%2Fhorus/lists"}