7rans

7rans

Update shorthand for Access behavor

I implemented Access behavior for a struct today. Pseudo-code…

defmodule MyStruct do
  defstruct data: %{}
  @behaviour Access
   # ... implementation of Access behavior on `data` ...
end

Then I tried:

  a = %{x: 1, y: 2}
  s = %MyStruct{data: a}
  z = %MyStruct{ s | y: 3 }

And of course it did not work.

Sure would be awesome if it could be made to work somehow though.

Most Liked

cmo

cmo

The way to achieve that is to have two function heads, one that matches on the struct and one that matches on the changeset. You can have the calculate logic in a separate private function and just extract the fields and put the result into whatever structure in each of the function heads.

And where are you going to get the other values for the calculation, if they’re not being passed as args? Passing required arguments to functions is not an antipattern :wink:

LostKobrakai

LostKobrakai

I think one thing is missing from this discussion and that‘s the notion of violating DRY by having ways to calculate the computed value from various sources of data. Instead of trying to avoid repetition by limiting the number of inputs (only struct or only changeset) you can also keep both inputs, but delegate the business logic in question to a shared helper.

def with_computed(%Ecto.Changeset{} = cs) do
  a = get_field(cs, :a)
  b = get_field(cs, :b)
  put_change(cs, :x, compute_x(a, b))
end

def with_computed(%Struct{} = struct) do
  %{struct | x: compute_x(struct.a, struct.b)}
end

defp compute_x(a, b), do: a + b
sodapopcan

sodapopcan

As @D4no0 said, it really sounds like you are trying to create class-like code. The problem with the code you showed us is that it just doubles down on why you think you need access. The real question is: “Why do you need a function that works on both in the first place?” The reason people are questioning you is because there shouldn’t be any reason to need to manually update a key of a schema’s struct, all changes should be done through changesets.

No such thing! Changeset constructors can look however you need to them to. The fact that cast_assoc will automagically look for a changeset/2 function is just a convenience. I won’t name names (@dimitarvp :sweat_smile:) but some people think this in-of-itself is a mistake and the :with option should always be used. Which is just a lot of words to try and re-enforce my point.

Where Next?

Popular in Proposals: Ideas Top

moacirbishopcamata
Good morning to the Elixir team. Please excuse me if I’m commenting in the wrong place; please indicate where I should discuss this. I ...
New
azyzz228
The slow network is known to be an Achilles heel of LiveView’s architecture. Recently, I was working on creating a fast rendering map wi...
New
manhvu
In a large repo, working with module need to add alias too much is quite annoyed and not good for organizing code. I think better add su...
New
virinchi_cv
The Problem Phoenix 1.8 comes aggressively coupled with Daisy UI, a decision which many developers in the community have had mixed feelin...
New
marcandre
I notice that most events have bindings (e.g. phx-keyup) but not the input event. The input event is the preferred way to interact with ...
New
shahryarjb
When proposing or suggesting something please consider: As my experience implementing getBoundingClientRect as Phoenix.LiveView.JS funct...
New
ffloyd
The Problem Currently, if I define a struct in the following way: defmodule MyStruct do # Both x and y will have the FIXED values unti...
New
dimitarvp
To @jonatanklosko and @the-mikedavis: I see that there is a Rust crate at crates.io: Rust Package Registry but it is pointing at https:/...
New
rmoorman
Current situation Currently, the structure of the HTML returned by phoenix is determined by the layouts (components/layouts/[root,app].ht...
New
sevensidedmarble
I have a very simple suggestion: the generated config/dev.exs file should read from PORT at compile time to set the endpoints port. If ...
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New

We're in Beta

About us Mission Statement