Introduction to Metaprogramming

The post belongs to NectarCommerce and Extension Framework Awareness

  1. NectarCommerce Vision

  2. Extension Framework Game Plan
  3. Introduction to Metaprogramming
  4. Ecto Model Schema Extension
  5. Ecto Model Support Functions Extension
  6. Phoenix Router Extension
  7. Phoenix View Extension
  8. Running Multiple Elixir Apps Together
  9. Extension Approach Explained
  10. Developer Experience and Workflow developing Favorite Product Extension
  11. Developer Experience and Workflow testing Favorite Product Extension

What will be NectarCommerce

Off-the-shelf Opensource E-commerce application for building an online store.

Provides an Extension Framework to support features not included in core as extensions.

Strives for unobtrusive parallel development of NectarCommerce and Extensions

NectarCommerce is committed to providing a ready-to-use e-commerce solution but the definition of 100% is different under different business domains. It aims to solve common use-cases as part of the project and relying on extension framework to tap the rest.

Metaprogramming in Elixir

If you are already familiar and experienced with Elixir Metaprogramming, you can jump toas it lists Metaprogramming resources

and constructs used in upcoming blogs when creating different extension DSL’s.

Elixir docs
are excellent resources to get familiar with Metaprogramming:

Check out
Understanding Elixir Macros blog

by @sasajuric


Metaprogramming Elixir

by @chris_mccord
is next step for diving deeper into metaprogramming.

Why another tutorial on an already well-documented metaprogramming topic ?

To revise and refresh something that we would refer time and again when reviewing Model, Router, View extension DSLs

Extension DSLs will be using below constructs to get the job done :)

  • Module.register_attribute/3

    • Registers an attribute. By registering an attribute
      , a developer is able to customize how Elixir will store and accumulate the attribute values.
  • Module.put_attribute/3

    • Puts an Erlang attribute to the given module with the given key and value
  • @before_compile

    • A hook __before_compile__/1
      that will be invoked before the module is compiled
    • It allows us to inject code into the module when its definition is complete
  • __using__ hook

    • Checkout the title Examples
      for the usage & context and Best practices
      in link above
    • use ModuleName
      looks and invokes __using__
      macro defined in ModuleName
  • bind_quoted

    • Find the documentation under title Options
      for bind_quoted option
      in the link above
    • By using bind_quoted
      , we can automatically disable unquoting while still injecting the desired variables into the tree
  • Code.ensure_loaded?/1

    • Ensures the given module is loaded
  • apply/3

    • Invokes the given function
      from module
      with the array of arguments args
  • Macro.escape/1

    • Recursively escapes a value so it can be inserted into a syntax tree

Metaprogramming pattern as used across extensions

Minimum three parts are needed to create & use an extension effectively:

  • Library Code
  • Service Code
  • Consumer Code

An extension and its use with Nectar can be viewed as Producer / Consumer relationship bound by a communication protocol.

Extensionwhich wants to add a route, say a list of favorites, is a Producer (Service Code)

Nectar Routeris a Consumer (Consumer Code)
allowing the route additions through a communication protocol (Library Code)

  • Library code
    defines a macro providing a DSL, say define_route
  • Collect all definitions provided using DSL from Service code
    in Module attribute, say defined_routes
  • Library code
    defines a before_compile
    hook to add a macro extracting all collected definitions from module attribute, as module attributes are cleaned up as compilation completes
  • Inject generated code into targeting module Consumer code
    through __using__
    hook as invoked by use ModuleWithDSLImplementation
    , say use ExtensionsManager.RouterExtension

Our aim with these posts is to start a dialog with the Elixir community on validity and technical soundness of our approach. We would really appreciate your feedback and reviews, and any ideas/suggestions/pull requests for improvements to our current implementation or entirely different and better way to do things to achieve the goals we have set out for NectarCommerce.

Enjoy the Elixir potion !!

稿源:Vinsol (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 综合编程 » Introduction to Metaprogramming

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录