Thanks, I guess I get it: INVERTING DATA ACCESS. might be what I need. Unfortunately, I am not a pro in either of the Langs you mentioned.
I will try inverting data access (possibly with the |> operator) and see where I can get.
Best,
Thanks, I guess I get it: INVERTING DATA ACCESS. might be what I need. Unfortunately, I am not a pro in either of the Langs you mentioned.
I will try inverting data access (possibly with the |> operator) and see where I can get.
Best,
Then try with any other language you are proficient with. We have quite some polyglots here in the forum.
From the questions you ask, it seems as if you have used at least one OOP language so far.
Yep this! I excessively know a lot of languages from C/C++ to Java to OCaml to Python to Perl to I’m learning Rust right now to so so so many more of various levels. A lot of people are like that here.
The BEAM is a great glue language to other languages too, I’ve known erlang since 2001 or so (maybe earlier, I remember when HiPE was added…). ^.^
Thanks Gentlemen,
I will provide all the modules that I have built. I have stripped many of them so that the code is not too bulky. Probably, by doing this (as a newbie) I may help others who may run into similar difficulties.
So far, I have 4 module: LangEngine.Type, LangEngine.Subtype, LangEngine.ContentObject, and LangEngine.Component.
defmodule LangEngine.Type do
@type_list [:text, :media, :widget]
def new(input) do
msg = "Your input is not a valid type"
case Enum.member?(@type_list, input) do
true -> input
false -> %{error: msg}
end
end
def new() do
msg = "You have not provided a type"
%{error: msg}
end
def valid_type?(type) do
case Enum.member?(@type_list, type) do
true -> true
false -> false
end
end
end
defmodule LangEngine.Subtype do
alias LangEngine.{Type}
@text_list [:h1, :h2, :h3, :h4, :h5, :h6, :p]
@media_list [:image, :audio, :video]
@widget_list [:button, :submit, :input, :password, :link, :textarea]
defstruct name: nil
def new(type, input) do
case Type.new(type) do
%{error: msg} -> %{error: msg}
:text -> validate_subtype(@text_list, :text, input)
:media -> validate_subtype(@media_list, :media, input)
:widget -> validate_subtype(@widget_list, :widget, input)
end
end
def new(_input) do
Type.new()
end
def validate_subtype(list, type, input) do
msg = "Your input (#{input}) is not a valid subtype of the provided type (#{type})"
case Enum.member?(list, input) do
true -> input
false -> %{error: msg}
end
end
def valid_subtype?(type, input) do
case new(type, input) do
%{error: _msg} -> false
_input -> true
end
end
end
defmodule LangEngine.ContentObject do
alias LangEngine.{ContentObject, Type, Subtype}
@enforce_keys [:id, :type, :subtype]
defstruct id: nil, type: nil, subtype: nil, content: nil
def new(id, type, subtype, content) do
if Type.valid_type?(type) == true do
if Subtype.valid_subtype?(type, subtype) == true do
%ContentObject{id: id,
type: type,
subtype: subtype,
content: content}
else
Subtype.new(type, subtype)
end
else
Type.new(type)
end
end
end
defmodule LangEngine.Component do
alias LangEngine.{Component}
@enforce_keys [:id, :content_objs]
defstruct [id: nil, content_objs: []]
def new(id, content) do
%Component{id: id, content_objs: [content]}
end
def simple_component_view(component) do
for obj <- component.content_objs do
%{:name => obj.id, :subtype => obj.subtype}
end
end
def update_component_content(component, new_content) do
%Component{id: component.id, content_objs: [new_content]}
end
end
These modules compile with no errors or complaints.
Now, back to my original question: It seems that I was thinking of a data of type “Component” as a container of ContentObject, and ContentObject as a container of Type and Subtype. I NOW think this is true, but not in the OOP way. The contained data in either ContentObject and Component are not objects with references. Once created, they are set. If I create a component with Component.new, what I will get is a piece of data, and not an object. What this means is if I now go and change one of the contained data pieces (say, the type or subtype) I will not get a new component immediately. I will need a function to do that. This is why I created a function in the Component Module with the name “update_component_content”.
The amazing thing is in iex I can have a variable and bind it to a new “component” with a certain “content object”, then go change that content object, then rebind my variable using “update_component_content” function, and when I ask iex for what value my variable is it will respond with the updated component, so to speak.
However trying to do this in a function in the Component module, and trying to pass a component as an argument gave me that warning of “… is not being used”.
I am sorry if I am taking too much space, or providing irrelevant details, but I think that providing some real code written by a newbie might shed a light on:
Many thanks again for all who have replied to me.
N.B: I tried my best not to use the term object so that NoobZ doesn’t flame me . Instead I used the word “data”.
Hassan
You can just not use data = … And just return your modified struct. No need to rebind it. That should get rid if the original error.