Note that both IEx and ExUnit already keep a wrapper around inspect as they do provide default inspecting values, so the explicit approach sounds like the way to go IMO.
*José Valim* www.plataformatec.com.br Skype: jv.ptec Founder and Director of R&D On Sun, Dec 16, 2018 at 9:14 PM <[email protected]> wrote: > > Couldn't you define a method like __record_keys__/0 on the atom in the > defrecord call? > > Yes. To be concrete, this is how it could work: > > ``` > defmodule Records do > import Record > defrecord :a, [:x, :y] > defrecord :b, [:x, :y] > end > > iex> Records.__records__() > [ > a: [:x, :y], > b: [:x, :y] > ] > ``` > > Alternatively, this could become `Records.__info__(:records)`. In either > case, to make this work I think we'd need `use Record`. Or, we'd have a new > `defrecords/1` that defines both multiple records as well as this > reflection function. > > > Unlike structs there's no guarantee that two records won't be defined > with the same name, they are scoped within modules. > > That's a good point. That's something I was aware of but I guess I haven't > thought through the consequences which I think are: if by doing `defrecord` > we'd store the fields somewhere (like the :persistent_term solution > mentioned) we'll need to handle duplicates by erroring or at least warning. > > For this reason, perhaps the other, "stateless", approach mentioned above > is more suitable? Users will opt-in to use records so they'll handle > conflicts themselves. > > I mentioned we can configure inspect behaviour with `IEx.configure`; the > `ExUnit.configure(inspect: ...) is not possible (I honestly thought it is) > so in order to format records in ExUnit diffs we'd need that. > Even if we configure both IEx and ExUnit to use record definitions, > anytime we do `IO.inspect(record)` we'd get non-formatted records output > and so to format it we'd have to keep inspect record options everywhere. To > take advantage of this feature we'd have to configure it in IEx, ExUnit and > all IO.inspect calls; that's explicit but doesn't sound practical. > > The only solutions I can think of at the moment are: > 1. Going back to magically keeping record fields > 2. Currently, we have essentially `Kernel.inspect(term, opts \\ [])`, > `IO.inspect(term, opts \\ [])`; if we change it something along the lines > of `Kernel.inspect(term, opts \\ default_opts())` and make these defaults > configurable we could configure our records just once. So we're back to > global state after all. > > Neither option is perfect. I'll continue experimenting with this as a > standalone library but it seems less likely it could be part of Elixir. > What do you think? > > On Sunday, December 16, 2018 at 3:47:57 PM UTC+1, Louis Pop wrote: >> >> Hey >> >> Unlike structs there's no guarantee that two records won't be defined >> with the same name, they are scoped within modules. >> >> Cheers, >> Louis >> >> On Sun, 16 Dec 2018 at 13:55 Allen Madsen <[email protected]> wrote: >> >>> Couldn't you define a method like __record_keys__/0 on the atom in the >>> defrecord call? >>> >>> Allen Madsen >>> http://www.allenmadsen.com >>> >>> >>> On Sat, Dec 15, 2018 at 11:49 AM <[email protected]> wrote: >>> >>>> One way to avoid issues with state is to avoid... state. Maybe we'd >>>> configure it like this: >>>> >>>> records = [ >>>> # explicit >>>> {:column_definition, [:name, :type]}, >>>> >>>> # grabs record fields from record macro in that module, e.g: >>>> resultset(resultset()) |> Keyword.keys() >>>> {Records, :resultset} >>>> ] >>>> >>>> IEx.configure(inspect: [records: records]) >>>> ExUnit.configure(inspect: [records: records]) >>>> >>>> This is less convenient, but I guess sometimes we may prefer the >>>> "tuple" representation so by making this opt-in we cater to that use case >>>> as well. >>>> >>>> On Saturday, December 15, 2018 at 5:08:13 PM UTC+1, >>>> [email protected] wrote: >>>>> >>>>> Hello, >>>>> I'd like to discuss support for Inspect protocol for records. I >>>>> created a proof-of-concept here: >>>>> https://github.com/wojtekmach/record_inspect >>>>> >>>>> Basically, for these records: >>>>> >>>>> defrecord :resultset [ >>>>> :column_count, >>>>> :column_definitions, >>>>> :row_count, >>>>> :rows, >>>>> :warning_count, >>>>> :status_flags >>>>> ] >>>>> >>>>> defrecord :column_definition41, [:name, :type] >>>>> >>>>> Instead of: >>>>> >>>>> {:resultset, 2, >>>>> [{:column_definition41, "2*3", 8}, {:column_definition41, "4*5", 8}], >>>>> 1, >>>>> [[6, 20]], 0, 2} >>>>> >>>>> We could get this: >>>>> >>>>> #resultset([ >>>>> column_count: 2, >>>>> column_definitions: [ >>>>> #column_definition41([name: "2*3", type: 8]), >>>>> #column_definition41([name: "4*5", type: 8]) >>>>> ], >>>>> row_count: 1, >>>>> rows: [[6, 20]], >>>>> warning_count: 0, >>>>> status_flags: 2 >>>>> ]) >>>>> >>>>> My proof-of-concept uses the new `:persistent_term` facility in OTP >>>>> 21.2 just to get something working. Managing the state is challenging for >>>>> potentially including this in Elixir. >>>>> >>>>> Feedback appreciated! >>>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "elixir-lang-core" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to [email protected]. >>>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/elixir-lang-core/8e936469-e806-46f9-b4a4-3aa3c577d205%40googlegroups.com >>>> <https://groups.google.com/d/msgid/elixir-lang-core/8e936469-e806-46f9-b4a4-3aa3c577d205%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> . >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "elixir-lang-core" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/elixir-lang-core/CAK-y3Ct-2iFCY12qQD07GurkkRepiN3vqaDVgML_7WpHctqLuA%40mail.gmail.com >>> <https://groups.google.com/d/msgid/elixir-lang-core/CAK-y3Ct-2iFCY12qQD07GurkkRepiN3vqaDVgML_7WpHctqLuA%40mail.gmail.com?utm_medium=email&utm_source=footer> >>> . >>> For more options, visit https://groups.google.com/d/optout. >>> >> -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/elixir-lang-core/ac5197ed-aadf-4b2c-b9bd-743eb14fe6d2%40googlegroups.com > <https://groups.google.com/d/msgid/elixir-lang-core/ac5197ed-aadf-4b2c-b9bd-743eb14fe6d2%40googlegroups.com?utm_medium=email&utm_source=footer> > . > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4JngVkysktibeGXEB0o3-KQttOjTK4cqUjHjZsVhwYKKw%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
