chemist

chemist

Hi, Im having a bit of trouble with anon. functions using the Vex validator.

defmodule Test do
  @enforce_keys [:wallet_id, :withdrawal, :currency, :funds_balance]

  defstruct [
    :wallet_id,
    :withdrawal,
    :currency,
    :funds_balance
  ]

  use ExConstructor
  use Vex.Struct
  alias __MODULE__

  validates(:withdrawal, presence: [message: "expected"], 
  by: [function: &Test.test(&1, Map.get(&2, :funds_balance)), 
  message: "invalid withdrawal."])

  def test(withdrawal, funds_balance) do
    # some logic here
  end
end

The above has two capture operators, &1 which is the field being validated: withdrawal and &2 which is the entire Test struct, %Test{}

Basically the above snippet results in this error:
** (ArgumentError) cannot inject attribute @vex_validations into function/macro because cannot escape function

I need a nested function that can effectively capture the second field, &2. I am aware that it is possible to move this function to the function, test but will like to learn if it is possible to do it as a nested function as part of an anonymous function

Many thanks.

Showing Posts 1 to 10

03juan

03juan

Providing a stacktrace of your error would help in debugging.

chemist

chemist OP

Many thanks. Not too sure if it helps but here goes.

== Compilation error in file test.ex ==
** (ArgumentError) cannot inject attribute @vex_validations into function/macro because
 cannot escape #Function<0.45330970/2 in :elixir_compiler_5.__MODULE__/1>. The 
 supported values are: lists, tuples, maps, atoms, numbers, bitstrings, PIDs and remote 
 functions in the format &Mod.fun/arity
    (elixir 1.13.2) lib/kernel.ex:3509: Kernel.do_at/5
    (elixir 1.13.2) expanding macro: Kernel.@/1
    (test 0.1.0) test.ex:1: Test.__vex_validations__/0
    (vex 0.9.0) d:/test.ex:1: Vex.Struct.__before_compile__/1
kartheek

kartheek

function is supposed to be capture like &Test.test/1 or &Test.test/2.

chemist

chemist OP

Hi kartheek, apologies but if i understood you correctly, you are saying change the statement to:

  validates(:withdrawal, presence: [message: "expected"], 
  by: [function: &Test.test/2(&1, Map.get(&2, :funds_balance)), 
  message: "invalid withdrawal."])

Adding the arity operator to the function &Test.test does not help.

kartheek

kartheek

Its supposed to be

 by: [function: &Test.test/2,

It accepts function of arity 1 or 2 - if it is 2 it is passing context as second param.

You might have to relook at your test function

03juan

03juan

Not always true as the examples show passing an anonymous function definition

Vex.Validators.By.validate(
  [], [function: fn (v) when is_list(v) -> :ok
                    (v) -> {:error, {:not_list, v}} end])
:ok

The docs say

Options

None, a function with arity 1 must be provided.

  • :function: The function to check. Should have an arity of 1 and return true/false.

But the code you posted does seem to accept arity 2.

I assumed validates can be called with 3 arguments, but the code only provides VexStruct.validates/2

kartheek

kartheek

OP is not using anonymous function - wants to invoke Test.test ?

chemist

chemist OP

  validates(:withdrawal, presence: [message: "expected"], 
  by: [function: &Test.test(&1, Map.get(&2, :funds_balance)), 
  message: "invalid withdrawal."])

Map.get(&2, :funds_balance) will evaluate to the value held in funds_balance and @enforce_keys guarantee a non nil value. And i have tested it with a non-nil value.

The function Test.test has an arity of 2 and accepts two values &1: withdrawal (which is being evaluated) and the outcome of evaluating Map.get&2: funds balance resulting in an evaluation which is either false or true

So as a result, the function for the validator above will return true or false.

What I believe is the anon function utilizing the Vex.validator does not seem to like having a nested function using a capture operator. So im checking my understanding.

03juan

03juan

Officially you can only have a function with arity 1. There seems to be some support within the code for arity 2 but the Vex.Struct implementation does not use it.

If you follow the Vex.Struct and Vex.Extract.Struct code you may be able to re-implement them to provide your own validates/3 that takes a context, but that would be a more advance solution at the moment.

I respectfully disagree. The Kernel.SpecialForms.&/1 docs say

Capture operator. Captures or creates an anonymous function.

So in this case OP is trying to create an anonymous 2-arity function that calls test/2, but the parsing of @validators is failing because it does seem to expect the form &function/arity

kartheek

kartheek

Check this issue - Compilation error with Vex.Struct validates by · Issue #11 · CargoSense/vex · GitHub

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews