# Lists

**URL:** <https://rubytalk.org/t/lists/75547>\
**Category:** ruby-talk\
**Created:** [15 August 2021 10:18 UTC](https://rubytalk.org/t/lists/75547 "2021-08-15T10:18:10Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Die\_Optimisten](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@Die\_Optimisten](https://rubytalk.org/u/Die_Optimisten)\
**Post date:** [15 August 2021 10:18 UTC](https://rubytalk.org/t/lists/75547/1 "2021-08-15T10:18:10Z")

</div>

Hi!

I want to implement a single/double chained list,  
what I've done looks to much complicated (better to do a whole rewrite!)  
- so: how would you do that (elegant!)  
Where (in which class) to put which methods?  
-three classes?? class1: Container for Lists, .new=\>List, methods list1+list2, list1==list2  
class2: Methods of list (List-Operations), methods: list1.name=...; list1.push el  
class3: ListElement +links, methods: Element.new, el1==el2  
class2+3 could be in one class, but list.new seems not to be compatible to element.new  
(both list.new\_element and list.new should be def initialize..., the get a new class-object!!)  
classes 1+2 could also be merged into 1 class (class+object-methods)  
BUT classes 1,2,3 can't be merged into one class -\> whats a nice elegant way to combine that all / how to "classify" it best?

(wanted) RESULT:

list1 = Lists.new(:listA, :double) # Lists: Storage for many lists  
# i would prefer: class DList \< Lists(type= :double); end; list1 = DList.new(:listA) # how to do that?  
list2 = Lists.new(:listB, :double)  
list2.details =\> {type: :double, name: :listB, count: 0 /\*Elements\*/ }  
Lists.count # 2 (Lists)

el1 = list1.new('abc')  
el2 = list1.new('def')  
el3 = ListA.new('ghi') # metaprogramming... # see below: #{Name}

list1.count # 3 Elements  
list1.name # :listA  
list1 # ['abc','def','ghi']  
list1.map{|el| el } # ['abc','def','ghi']  
list1.find('def').previous # 'abc'  
list1.delete 'def'  
list3 = list(1) + list(2) ## Lists.count+=1, because of list3=... ! ???  
list2.destroy # removes Elements and list  
Lists.count # 2

thank you!  
---- (my try / forget the rest:) ---

class Lists  
@@allLists = {}

def initialize(listname) # new list  
erg = [] # should be List.new !  
@@allLists[listname] = erg  
return erg  
end

def delete(name)  
@@allLists -= @@allList[name]  
end

def names  
@@allLists.keys  
end  
def count  
@@allLists.count  
end

end

class List  
def initialize(listname,type=:double) # new list(!)  
@name=listname  
@erg = [] # for example  
@@allLists[listname] \<\< erg  
return @erg  
end

def type # :no, :single or :double # -chained list (:no=array)  
@type  
end

def name=newname # Name of List =\> How can I then use #{Name}.new ?  
@name=newname  
end  
def name  
@name  
end

def destroy # self  
Lists.delete self.name  
@erg.map{|el| el.destroy } # free it ??  
@erg = nil  
self.destroy # free self ??  
end

def add\_new(obj) # Element!  
el = Element.new(obj)  
@erg[-1][1][1] = self # set "Pointer" in previous element to this one  
if self.type==:double then self[1][0] = @erg[-1] end # set prev ptr  
@erg \<\< el # add element to list  
end

def push  
add\_new(obj)  
end

def pop

end

def first  
@erg[0]  
end

def last  
@erg[-1]  
end

def insert\_at  
end

def delete\_at  
end

def next  
el.previous # ??? # call next from class Element  
end

def previous  
el.next # ??? # class Element  
end

@list\_pos=-1  
def each  
if @list\_pos\<@erg.length then  
@list\_pos+=1  
"return" @erg  
end  
## @erg.each{|el| el ... } # how to return  
end

def reset  
@list\_pos=-1  
end

def count # of elements  
self.length  
end  
def remove\_element(pos)  
@erg[pos].delete # class Element

end

class Element  
def initialize(obj) # new element  
@erg = [obj,[previousEl,nextEl]]  
end  
def delete  
self=nil # how to destroy the whole instance?  
end

def previousEl # of self  
@erg[1][0]  
end

def nextEl # of self  
@erg[1][1]  
end

end

---

<div class="post-metadata">

**Author:** ![Mohit\_Sindhwani1](https://avatars.discourse-cdn.com/v4/letter/m/dbc845/32.png) [@Mohit\_Sindhwani1](https://rubytalk.org/u/Mohit_Sindhwani1)\
**Post date:** [15 August 2021 15:18 UTC](https://rubytalk.org/t/lists/75547/2 "2021-08-15T15:18:08Z")

</div>

Hi!

> I want to implement a single/double chained list,  
> what I've done looks to much complicated (better to do a whole rewrite!)  
> - so: how would you do that (elegant!)  
> Where (in which class) to put which methods?  
> -three classes?? class1: Container for Lists, .new=\>List, methods list1+list2, list1==list2  
> class2: Methods of list (List-Operations), methods: list1.name=...; list1.push el  
> class3: ListElement +links, methods: Element.new, el1==el2  
> class2+3 could be in one class, but list.new seems not to be compatible to element.new  
> (both list.new\_element and list.new should be def initialize..., the get a new class-object!!)  
> classes 1+2 could also be merged into 1 class (class+object-methods)  
> BUT classes 1,2,3 can't be merged into one class -\> whats a nice elegant way to combine that all / how to "classify" it best?

I would start with the idea that a list \*is\* a container. So, it should be treated similar to an array, hash, etc. since it stores elements. Starting with that idea, I would consider the following items:  
\* A list can store elements of any class - like a hash or array can  
\* Of course, internally, a list needs to have a way to maintain the data... in that, "element.new" would be an internal thing - in that sense, I would have that as a separate class. So, the "element" class is a wrapper with links and the main payload  
\* I would consider bringing in Enumerable into the picture so that you can benefit from what it provides

AppSignal has a write-up on enumerable which shows up on page 1 of Google if you search for 'ruby enumerable' but be warned - it has a Linked List example in the post 🙂

(By the way, I would not create a container for storing ALL lists unless you have a specific reason you need it. I would imagine that someone would put those into a hash, array or build a custom class if they really need it)

Best Regards,  
Mohit.  
2021-8-15 | 11:17 pm.

> **···**
>
> On 2021-8-15 6:18 pm, Die Optimisten wrote:

---

<div class="post-metadata">

**Author:** ![Surya](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/surya/32/2391_2.png) [@Surya](https://rubytalk.org/u/Surya)\
**Post date:** [15 August 2021 16:26 UTC](https://rubytalk.org/t/lists/75547/3 "2021-08-15T16:26:59Z")

</div>

I'd probably use 2 classes: List and Node, where List will have an instance  
var head accessible as reader(attrr\_reader :head). While Node will contain  
value/data instance var and the next\_node instance var that points to  
another Node instance.

> **···**
>
> On Sun, 15 Aug 2021 at 15:48, Die Optimisten \<inform@die-optimisten.net\> wrote:
> 
> > Hi!
> > 
> > I want to implement a single/double chained list,  
> > what I've done looks to much complicated (better to do a whole rewrite!)  
> > - so: how would you do that (elegant!)  
> > Where (in which class) to put which methods?  
> > &nbsp;&nbsp;-three classes?? class1: Container for Lists, .new=\>List, methods  
> > list1+list2, list1==list2  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class2: Methods of list  
> > (List-Operations), methods: list1.name=...; list1.push el  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class3: ListElement +links, methods:  
> > Element.new, el1==el2  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class2+3 could be in one class, but list.new seems not to  
> > be compatible to element.new  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(both list.new\_element and list.new should be def  
> > initialize..., the get a new class-object!!)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;classes 1+2 could also be merged into 1 class  
> > (class+object-methods)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BUT classes 1,2,3 can't be merged into one class -\> whats a  
> > nice elegant way to combine that all / how to "classify" it best?
> > 
> > (wanted) RESULT:
> > 
> > list1 = Lists.new(:listA, :double) # Lists: Storage for many lists  
> > &nbsp;&nbsp;&nbsp;# i would prefer: class DList \< Lists(type= :double); end; list1 =  
> > DList.new(:listA) # how to do that?  
> > list2 = Lists.new(:listB, :double)  
> > list2.details =\> {type: :double, name: :listB, count: 0 /\*Elements\*/ }  
> > Lists.count # 2 (Lists)
> > 
> > el1 = list1.new('abc')  
> > el2 = list1.new('def')  
> > el3 = ListA.new('ghi') # metaprogramming... # see below: #{Name}
> > 
> > list1.count # 3 Elements  
> > list1.name # :listA  
> > list1 # ['abc','def','ghi']  
> > list1.map{|el| el } # ['abc','def','ghi']  
> > list1.find('def').previous # 'abc'  
> > list1.delete 'def'  
> > list3 = list(1) + list(2) ## Lists.count+=1, because of list3=... ! ???  
> > list2.destroy # removes Elements and list  
> > Lists.count # 2
> > 
> > thank you!  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;---- (my try / forget the rest:) ---
> > 
> > class Lists  
> > &nbsp;&nbsp;&nbsp;@@allLists = {}
> > 
> > &nbsp;&nbsp;&nbsp;def initialize(listname) # new list  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;erg = # should be List.new !  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists[listname] = erg  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return erg  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def delete(name)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists -= @@allList[name]  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def names  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists.keys  
> > &nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;def count  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists.count  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > end
> > 
> > class List  
> > &nbsp;&nbsp;&nbsp;def initialize(listname,type=:double) # new list(!)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name=listname  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg = # for example  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists[listname] \<\< erg  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @erg  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def type # :no, :single or :double # -chained list (:no=array)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@type  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def name=newname # Name of List =\> How can I then use #{Name}.new ?  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name=newname  
> > &nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;def name  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def destroy # self  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Lists.delete self.name  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg.map{|el| el.destroy } # free it ??  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg = nil  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.destroy # free self ??  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def add\_new(obj) # Element!  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el = Element.new(obj)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[-1][1][1] = self # set "Pointer" in previous element to  
> > this one  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if self.type==:double then self[1][0] = @erg[-1] end # set prev ptr  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg \<\< el # add element to list  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def push  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add\_new(obj)  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def pop
> > 
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def first  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[0]  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def last  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[-1]  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def insert\_at  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def delete\_at  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def next  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el.previous # ??? # call next from class Element  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def previous  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el.next # ??? # class Element  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;@list\_pos=-1  
> > &nbsp;&nbsp;&nbsp;def each  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @list\_pos\<@erg.length then  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@list\_pos+=1  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"return" @erg  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;## @erg.each{|el| el ... } # how to return  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def reset  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@list\_pos=-1  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def count # of elements  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.length  
> > &nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;def remove\_element(pos)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[pos].delete # class Element
> > 
> > end
> > 
> > class Element  
> > &nbsp;&nbsp;&nbsp;def initialize(obj) # new element  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg = [obj,[previousEl,nextEl]]  
> > &nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;def delete  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self=nil # how to destroy the whole instance?  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def previousEl # of self  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[1][0]  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def nextEl # of self  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[1][1]  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > end
> > 
> > Unsubscribe: \<mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe\>  
> > \<[http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt](http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt);
> 
> --
> 
> Please consider the environment before printing this email.
> 
> Regards,  
> Surya

---

<div class="post-metadata">

**Author:** ![Dmitriy\_Non](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/dmitriy_non/32/1842_2.png) [@Dmitriy\_Non](https://rubytalk.org/u/Dmitriy_Non)\
**Post date:** [15 August 2021 21:47 UTC](https://rubytalk.org/t/lists/75547/4 "2021-08-15T21:47:05Z")

</div>

Hey,

List is a relatively primitive data structure by itself. It all comes down to what you wanna use it for.  
Generally, I prefer to implement lists as a pair `(value; rest of the list)`. You don't really need  
anything else in terms of the data structure itself.

From your code under "(wanted) RESULT:" I can tell that you want to have, basically, a stateful  
singleton factory (Lists.new being the factory and `Lists.count` pointing out that it's stateful and  
keeps track of its calls).  
Also you, seemingly, want to sit on two chairs by making your factory create both normal list and  
bi-directional one (:double argument). This seems like an overcomplication; separate them?  
Some of the results in the comments don't even make sense to me (e.g. list.destroy doesn't  
change Lists.count)

My advice is to try and revise your requirements first. Do you really need all these methods?  
If you really do you should try and distribute responsibilities over multiple classes so every one is  
simple and predictable in its nature.

My personal code style would probably be a somewhat mix of functional and object-oriented programming:  
- `List.new(head, tail)` - head being a value and tail being another list. This is a behaviourless struct.  
- `ListOperations::....` - a module with operations over lists like iteration, search, removing.  
&nbsp;&nbsp;All being immutable and returning a new list (where needed).

The above is basically all the basis you need. Now you need to implement the stuff specific for \*your\* case.  
If you need a stateful factory - create one.  
If you need a some kind of stateful wrapper over List, you can create one (just a class that contains a list  
and performs operations on it).

The most important part - try to distribute responsibilities between small parts and just combine (compose)  
them with each other. This way your code will have some sort of tree-like hierarchy and you'll probably  
have easier time working with it (because you will be able to navigate it from top to bottom as opposed to  
having a one big mess).

I hope it'll give you some ideas. But first of all carefuly think about what you actually want before  
designing/coding anything. Work backwards.

P.S. some additional comments:  
- technically, you don't need to delete anything in ruby. As soon as there're no references to an object it  
&nbsp;&nbsp;will be deleted, basically. This means that `destroy` is not an object's responsibility. You probably  
&nbsp;&nbsp;got this idea from Rails' ActiveRecord where its instances do all sorts of stuff. But in reality,  
&nbsp;&nbsp;those are just factory/etc methods that could (and, some would argue, should) be in a separate class.  
- I believe using class variables (`@@my_var`) is a bad practice. Consider something else. In my experience,  
&nbsp;&nbsp;you never need singletons. And even if you do, it's usually more intuitive to use Java-style singletons  
&nbsp;&nbsp;(MyClass.get\_instance, see `Singleton` module from stdlib).  
- You mix camel-case and snake-case naming. Not sure if it's intentional but it's certainly not conventional.

> **···**
>
> --------------------------  
> Dmitry Non
> 
> > **[Dmitry Non](https://nondv.wtf)**
> >
> > Personal blog and CV
> 
> > **[Weird programming](https://weird-programming.dev)**
> >
> > Programming blog exploring some weird and crazy ideas.
> 
> > On 15 Aug 2021, at 11:18, Die Optimisten \<inform@die-optimisten.net\> wrote:
> > 
> > Hi!
> > 
> > I want to implement a single/double chained list,  
> > what I've done looks to much complicated (better to do a whole rewrite!)  
> > - so: how would you do that (elegant!)  
> > Where (in which class) to put which methods?  
> > -three classes?? class1: Container for Lists, .new=\>List, methods list1+list2, list1==list2  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class2: Methods of list (List-Operations), methods: list1.name=...; list1.push el  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class3: ListElement +links, methods: Element.new, el1==el2  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class2+3 could be in one class, but list.new seems not to be compatible to element.new  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(both list.new\_element and list.new should be def initialize..., the get a new class-object!!)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;classes 1+2 could also be merged into 1 class (class+object-methods)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BUT classes 1,2,3 can't be merged into one class -\> whats a nice elegant way to combine that all / how to "classify" it best?
> > 
> > (wanted) RESULT:
> > 
> > list1 = Lists.new(:listA, :double) # Lists: Storage for many lists  
> > &nbsp;&nbsp;# i would prefer: class DList \< Lists(type= :double); end; list1 = DList.new(:listA) # how to do that?  
> > list2 = Lists.new(:listB, :double)  
> > list2.details =\> {type: :double, name: :listB, count: 0 /\*Elements\*/ }  
> > Lists.count # 2 (Lists)
> > 
> > el1 = list1.new('abc')  
> > el2 = list1.new('def')  
> > el3 = ListA.new('ghi') # metaprogramming... # see below: #{Name}
> > 
> > list1.count # 3 Elements  
> > list1.name # :listA  
> > list1 # ['abc','def','ghi']  
> > list1.map{|el| el } # ['abc','def','ghi']  
> > list1.find('def').previous # 'abc'  
> > list1.delete 'def'  
> > list3 = list(1) + list(2) ## Lists.count+=1, because of list3=... ! ???  
> > list2.destroy # removes Elements and list  
> > Lists.count # 2
> > 
> > thank you!  
> > &nbsp;&nbsp;&nbsp;&nbsp;---- (my try / forget the rest:) ---
> > 
> > class Lists  
> > &nbsp;&nbsp;@@allLists = {}
> > 
> > &nbsp;&nbsp;def initialize(listname) # new list  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;erg = # should be List.new !  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists[listname] = erg  
> > &nbsp;&nbsp;&nbsp;&nbsp;return erg  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def delete(name)  
> > &nbsp;&nbsp;&nbsp;&nbsp;@@allLists -= @@allList[name]  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def names  
> > &nbsp;&nbsp;&nbsp;&nbsp;@@allLists.keys  
> > &nbsp;&nbsp;end  
> > &nbsp;&nbsp;def count  
> > &nbsp;&nbsp;&nbsp;&nbsp;@@allLists.count  
> > &nbsp;&nbsp;end
> > 
> > end
> > 
> > class List  
> > &nbsp;&nbsp;def initialize(listname,type=:double) # new list(!)  
> > &nbsp;&nbsp;&nbsp;&nbsp;@name=listname  
> > &nbsp;&nbsp;&nbsp;&nbsp;@erg = # for example  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists[listname] \<\< erg  
> > &nbsp;&nbsp;&nbsp;&nbsp;return @erg  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def type # :no, :single or :double # -chained list (:no=array)  
> > &nbsp;&nbsp;&nbsp;&nbsp;@type  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def name=newname # Name of List =\> How can I then use #{Name}.new ?  
> > &nbsp;&nbsp;&nbsp;&nbsp;@name=newname  
> > &nbsp;&nbsp;end  
> > &nbsp;&nbsp;def name  
> > &nbsp;&nbsp;&nbsp;&nbsp;@name  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def destroy # self  
> > &nbsp;&nbsp;&nbsp;&nbsp;Lists.delete self.name  
> > &nbsp;&nbsp;&nbsp;&nbsp;@erg.map{|el| el.destroy } # free it ??  
> > &nbsp;&nbsp;&nbsp;&nbsp;@erg = nil  
> > &nbsp;&nbsp;&nbsp;&nbsp;self.destroy # free self ??  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def add\_new(obj) # Element!  
> > &nbsp;&nbsp;&nbsp;&nbsp;el = Element.new(obj)  
> > &nbsp;&nbsp;&nbsp;&nbsp;@erg[-1][1][1] = self # set "Pointer" in previous element to this one  
> > &nbsp;&nbsp;&nbsp;&nbsp;if self.type==:double then self[1][0] = @erg[-1] end # set prev ptr  
> > &nbsp;&nbsp;&nbsp;&nbsp;@erg \<\< el # add element to list  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def push  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add\_new(obj)  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def pop
> > 
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def first  
> > &nbsp;&nbsp;&nbsp;&nbsp;@erg[0]  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def last  
> > &nbsp;&nbsp;&nbsp;&nbsp;@erg[-1]  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def insert\_at  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def delete\_at  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def next  
> > &nbsp;&nbsp;&nbsp;&nbsp;el.previous # ??? # call next from class Element  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def previous  
> > &nbsp;&nbsp;&nbsp;&nbsp;el.next # ??? # class Element  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;@list\_pos=-1  
> > &nbsp;&nbsp;def each  
> > &nbsp;&nbsp;&nbsp;&nbsp;if @list\_pos\<@erg.length then  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@list\_pos+=1  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"return" @erg  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;## @erg.each{|el| el ... } # how to return  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def reset  
> > &nbsp;&nbsp;&nbsp;&nbsp;@list\_pos=-1  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def count # of elements  
> > &nbsp;&nbsp;&nbsp;&nbsp;self.length  
> > &nbsp;&nbsp;end  
> > &nbsp;&nbsp;def remove\_element(pos)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[pos].delete # class Element
> > 
> > end
> > 
> > class Element  
> > &nbsp;&nbsp;def initialize(obj) # new element  
> > &nbsp;&nbsp;&nbsp;&nbsp;@erg = [obj,[previousEl,nextEl]]  
> > &nbsp;&nbsp;end  
> > &nbsp;&nbsp;def delete  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self=nil # how to destroy the whole instance?  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def previousEl # of self  
> > &nbsp;&nbsp;&nbsp;&nbsp;@erg[1][0]  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;def nextEl # of self  
> > &nbsp;&nbsp;&nbsp;&nbsp;@erg[1][1]  
> > &nbsp;&nbsp;end
> > 
> > end
> > 
> > Unsubscribe: \<mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe\>  
> > \<[http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt](http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt);

---

<div class="post-metadata">

**Author:** ![Die\_Optimisten](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@Die\_Optimisten](https://rubytalk.org/u/Die_Optimisten)\
**Post date:** [16 August 2021 11:40 UTC](https://rubytalk.org/t/lists/75547/5 "2021-08-16T11:40:20Z")

</div>

Hello,  
Thanks for your answers!  
It's more about learning (the handling of) Ruby, "lists" is just an example.  
Factoring / other good things: Could you give me an illustration,  
or - would it be possible to create it in common (in the community)? -  
Example of "How to use Ruby the right (best) way"

Yes, count (and other details) are not written down in this example  
(focussing on the big/important thinks). -\> How to .destroy??  
Why is a factory class better than a super-class?  
What about the organisation of the classses? (which methods in which  
class?; see below),  
The aim is to reuse most of the code. so no thing should be done twice  
(therefore array/single-/double-linked with one super-class). -- It's not a  
So I want the "best possible Ruby-Program"\*) for that  
\*)...1) nice/good 2)short code. 3) innovative [show the features of  
Ruby], but easy to understand, 4) low mem/5) cpu - usage [something  
foregotten?? ] 🙂  
Any ideas ?

thank you  
Opti

> **···**
>
> Am 15.08.21 um 23:47 schrieb Dmitriy Non:
> 
> > Hey,
> > 
> > List is a relatively primitive data structure by itself. It all comes down to what you wanna use it for.  
> > Generally, I prefer to implement lists as a pair `(value; rest of the list)`. You don't really need  
> > anything else in terms of the data structure itself.
> > 
> > From your code under "(wanted) RESULT:" I can tell that you want to have, basically, a stateful  
> > singleton factory (Lists.new being the factory and `Lists.count` pointing out that it's stateful and keeps track of its calls).  
> > Also you, seemingly, want to sit on two chairs by making your factory create both normal list and  
> > bi-directional one (:double argument). This seems like an overcomplication; separate them?  
> > Some of the results in the comments don't even make sense to me (e.g. list.destroy doesn't  
> > change Lists.count)
> > 
> > My advice is to try and revise your requirements first. Do you really need all these methods?  
> > If you really do you should try and distribute responsibilities over multiple classes so every one is  
> > simple and predictable in its nature.
> > 
> > My personal code style would probably be a somewhat mix of functional and object-oriented programming:  
> > - `List.new(head, tail)` - head being a value and tail being another list. This is a behaviourless struct.  
> > - `ListOperations::....` - a module with operations over lists like iteration, search, removing.  
> > &nbsp;&nbsp;&nbsp;All being immutable and returning a new list (where needed).
> > 
> > The above is basically all the basis you need. Now you need to implement the stuff specific for \*your\* case.  
> > If you need a stateful factory - create one.  
> > If you need a some kind of stateful wrapper over List, you can create one (just a class that contains a list  
> > and performs operations on it).
> > 
> > The most important part - try to distribute responsibilities between small parts and just combine (compose)  
> > them with each other. This way your code will have some sort of tree-like hierarchy and you'll probably  
> > have easier time working with it (because you will be able to navigate it from top to bottom as opposed to  
> > having a one big mess).
> > 
> > I hope it'll give you some ideas. But first of all carefuly think about what you actually want before  
> > designing/coding anything. Work backwards.
> > 
> > P.S. some additional comments:  
> > - technically, you don't need to delete anything in ruby. As soon as there're no references to an object it  
> > &nbsp;&nbsp;&nbsp;will be deleted, basically. This means that `destroy` is not an object's responsibility. You probably  
> > &nbsp;&nbsp;&nbsp;got this idea from Rails' ActiveRecord where its instances do all sorts of stuff. But in reality,  
> > &nbsp;&nbsp;&nbsp;those are just factory/etc methods that could (and, some would argue, should) be in a separate class.  
> > - I believe using class variables (`@@my_var`) is a bad practice. Consider something else. In my experience,  
> > &nbsp;&nbsp;&nbsp;you never need singletons. And even if you do, it's usually more intuitive to use Java-style singletons  
> > &nbsp;&nbsp;&nbsp;(MyClass.get\_instance, see `Singleton` module from stdlib).  
> > - You mix camel-case and snake-case naming. Not sure if it's intentional but it's certainly not conventional.
> > 
> > --------------------------  
> > Dmitry Non  
> > [https://nondv.wtf](https://nondv.wtf)  
> > [https://weird-programming.dev](https://weird-programming.dev)
> > 
> > > On 15 Aug 2021, at 11:18, Die Optimisten \<inform@die-optimisten.net\> wrote:
> > > 
> > > Hi!
> > > 
> > > I want to implement a single/double chained list,  
> > > what I've done looks to much complicated (better to do a whole rewrite!)  
> > > - so: how would you do that (elegant!)  
> > > Where (in which class) to put which methods?  
> > > &nbsp;&nbsp;-three classes?? class1: Container for Lists, .new=\>List, methods list1+list2, list1==list2  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class2: Methods of list (List-Operations), methods: list1.name=...; list1.push el  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class3: ListElement +links, methods: Element.new, el1==el2  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class2+3 could be in one class, but list.new seems not to be compatible to element.new  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(both list.new\_element and list.new should be def initialize..., the get a new class-object!!)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;classes 1+2 could also be merged into 1 class (class+object-methods)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BUT classes 1,2,3 can't be merged into one class -\> whats a nice elegant way to combine that all / how to "classify" it best?
> > > 
> > > (wanted) RESULT:
> > > 
> > > list1 = Lists.new(:listA, :double) # Lists: Storage for many lists  
> > > &nbsp;&nbsp;&nbsp;# i would prefer: class DList \< Lists(type= :double); end; list1 = DList.new(:listA) # how to do that?  
> > > list2 = Lists.new(:listB, :double)  
> > > list2.details =\> {type: :double, name: :listB, count: 0 /\*Elements\*/ }  
> > > Lists.count # 2 (Lists)
> > > 
> > > el1 = list1.new('abc')  
> > > el2 = list1.new('def')  
> > > el3 = ListA.new('ghi') # metaprogramming... # see below: #{Name}
> > > 
> > > list1.count # 3 Elements  
> > > list1.name # :listA  
> > > list1 # ['abc','def','ghi']  
> > > list1.map{|el| el } # ['abc','def','ghi']  
> > > list1.find('def').previous # 'abc'  
> > > list1.delete 'def'  
> > > list3 = list(1) + list(2) ## Lists.count+=1, because of list3=... ! ???  
> > > list2.destroy # removes Elements and list  
> > > Lists.count # 2
> > > 
> > > thank you!  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;---- (my try / forget the rest:) ---
> > > 
> > > class Lists  
> > > &nbsp;&nbsp;&nbsp;@@allLists = {}
> > > 
> > > &nbsp;&nbsp;&nbsp;def initialize(listname) # new list  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;erg = # should be List.new !  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists[listname] = erg  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return erg  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def delete(name)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists -= @@allList[name]  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def names  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists.keys  
> > > &nbsp;&nbsp;&nbsp;end  
> > > &nbsp;&nbsp;&nbsp;def count  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists.count  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > end
> > > 
> > > class List  
> > > &nbsp;&nbsp;&nbsp;def initialize(listname,type=:double) # new list(!)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name=listname  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg = # for example  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@allLists[listname] \<\< erg  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @erg  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def type # :no, :single or :double # -chained list (:no=array)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@type  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def name=newname # Name of List =\> How can I then use #{Name}.new ?  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name=newname  
> > > &nbsp;&nbsp;&nbsp;end  
> > > &nbsp;&nbsp;&nbsp;def name  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def destroy # self  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Lists.delete self.name  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg.map{|el| el.destroy } # free it ??  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg = nil  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.destroy # free self ??  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def add\_new(obj) # Element!  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el = Element.new(obj)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[-1][1][1] = self # set "Pointer" in previous element to this one  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if self.type==:double then self[1][0] = @erg[-1] end # set prev ptr  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg \<\< el # add element to list  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def push  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add\_new(obj)  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def pop
> > > 
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def first  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[0]  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def last  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[-1]  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def insert\_at  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def delete\_at  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def next  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el.previous # ??? # call next from class Element  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def previous  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el.next # ??? # class Element  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;@list\_pos=-1  
> > > &nbsp;&nbsp;&nbsp;def each  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @list\_pos\<@erg.length then  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@list\_pos+=1  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"return" @erg  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;## @erg.each{|el| el ... } # how to return  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def reset  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@list\_pos=-1  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def count # of elements  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.length  
> > > &nbsp;&nbsp;&nbsp;end  
> > > &nbsp;&nbsp;&nbsp;def remove\_element(pos)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[pos].delete # class Element
> > > 
> > > end
> > > 
> > > class Element  
> > > &nbsp;&nbsp;&nbsp;def initialize(obj) # new element  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg = [obj,[previousEl,nextEl]]  
> > > &nbsp;&nbsp;&nbsp;end  
> > > &nbsp;&nbsp;&nbsp;def delete  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self=nil # how to destroy the whole instance?  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def previousEl # of self  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[1][0]  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def nextEl # of self  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@erg[1][1]  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > end

---

<div class="post-metadata">

**Author:** ![Die\_Optimisten](https://avatars.discourse-cdn.com/v4/letter/d/f04885/32.png) [@Die\_Optimisten](https://rubytalk.org/u/Die_Optimisten)\
**Post date:** [16 August 2021 11:44 UTC](https://rubytalk.org/t/lists/75547/6 "2021-08-16T11:44:42Z")

</div>

Maybe - if it makes more sense, we can adapt the request, too!

Opti

---

<div class="post-metadata">

**Author:** ![Martin\_DeMello](https://avatars.discourse-cdn.com/v4/letter/m/f17d59/32.png) [@Martin\_DeMello](https://rubytalk.org/u/Martin_DeMello)\
**Post date:** [16 August 2021 18:56 UTC](https://rubytalk.org/t/lists/75547/7 "2021-08-16T18:56:41Z")

</div>

For "how to use ruby the right/best way", this is a great book:

> **[Practical Object-Oriented Design in Ruby](https://www.poodr.com/)**

martin

> **···**
>
> On Mon, Aug 16, 2021 at 4:40 AM Die Optimisten \<inform@die-optimisten.net\> wrote:
> 
> > Hello,  
> > Thanks for your answers!  
> > It's more about learning (the handling of) Ruby, "lists" is just an  
> > example.  
> > Factoring / other good things: Could you give me an illustration,  
> > or - would it be possible to create it in common (in the community)? -  
> > Example of "How to use Ruby the right (best) way"
> > 
> > Yes, count (and other details) are not written down in this example  
> > (focussing on the big/important thinks). -\> How to .destroy??  
> > Why is a factory class better than a super-class?  
> > What about the organisation of the classses? (which methods in which  
> > class?; see below),  
> > The aim is to reuse most of the code. so no thing should be done twice  
> > (therefore array/single-/double-linked with one super-class). -- It's not a  
> > So I want the "best possible Ruby-Program"\*) for that  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\*)...1) nice/good 2)short code. 3) innovative [show the features of  
> > Ruby], but easy to understand, 4) low mem/5) cpu - usage [something  
> > foregotten?? ] 🙂  
> > Any ideas ?
> > 
> > thank you  
> > Opti
> > 
> > Am 15.08.21 um 23:47 schrieb Dmitriy Non:  
> > \> Hey,  
> > \>  
> > \> List is a relatively primitive data structure by itself. It all comes  
> > down to what you wanna use it for.  
> > \> Generally, I prefer to implement lists as a pair `(value; rest of the  
> > list)`. You don't really need  
> > \> anything else in terms of the data structure itself.  
> > \>  
> > \> From your code under "(wanted) RESULT:" I can tell that you want to  
> > have, basically, a stateful  
> > \> singleton factory (Lists.new being the factory and `Lists.count`  
> > pointing out that it's stateful and keeps track of its calls).  
> > \> Also you, seemingly, want to sit on two chairs by making your factory  
> > create both normal list and  
> > \> bi-directional one (:double argument). This seems like an  
> > overcomplication; separate them?  
> > \> Some of the results in the comments don't even make sense to me (e.g.  
> > list.destroy doesn't  
> > \> change Lists.count)  
> > \>  
> > \> My advice is to try and revise your requirements first. Do you really  
> > need all these methods?  
> > \> If you really do you should try and distribute responsibilities over  
> > multiple classes so every one is  
> > \> simple and predictable in its nature.  
> > \>  
> > \> My personal code style would probably be a somewhat mix of functional  
> > and object-oriented programming:  
> > \> - `List.new(head, tail)` - head being a value and tail being another  
> > list. This is a behaviourless struct.  
> > \> - `ListOperations::....` - a module with operations over lists like  
> > iteration, search, removing.  
> > \> All being immutable and returning a new list (where needed).  
> > \>  
> > \> The above is basically all the basis you need. Now you need to implement  
> > the stuff specific for \*your\* case.  
> > \> If you need a stateful factory - create one.  
> > \> If you need a some kind of stateful wrapper over List, you can create  
> > one (just a class that contains a list  
> > \> and performs operations on it).  
> > \>  
> > \> The most important part - try to distribute responsibilities between  
> > small parts and just combine (compose)  
> > \> them with each other. This way your code will have some sort of  
> > tree-like hierarchy and you'll probably  
> > \> have easier time working with it (because you will be able to navigate  
> > it from top to bottom as opposed to  
> > \> having a one big mess).  
> > \>  
> > \> I hope it'll give you some ideas. But first of all carefuly think about  
> > what you actually want before  
> > \> designing/coding anything. Work backwards.  
> > \>  
> > \> P.S. some additional comments:  
> > \> - technically, you don't need to delete anything in ruby. As soon as  
> > there're no references to an object it  
> > \> will be deleted, basically. This means that `destroy` is not an  
> > object's responsibility. You probably  
> > \> got this idea from Rails' ActiveRecord where its instances do all  
> > sorts of stuff. But in reality,  
> > \> those are just factory/etc methods that could (and, some would argue,  
> > should) be in a separate class.  
> > \> - I believe using class variables (`@@my_var`) is a bad practice.  
> > Consider something else. In my experience,  
> > \> you never need singletons. And even if you do, it's usually more  
> > intuitive to use Java-style singletons  
> > \> (MyClass.get\_instance, see `Singleton` module from stdlib).  
> > \> - You mix camel-case and snake-case naming. Not sure if it's intentional  
> > but it's certainly not conventional.  
> > \>  
> > \>  
> > \> --------------------------  
> > \> Dmitry Non  
> > \> [https://nondv.wtf](https://nondv.wtf)  
> > \> [https://weird-programming.dev](https://weird-programming.dev)  
> > \>  
> > \>\> On 15 Aug 2021, at 11:18, Die Optimisten \<inform@die-optimisten.net\> \> wrote:  
> > \>\>  
> > \>\> Hi!  
> > \>\>  
> > \>\> I want to implement a single/double chained list,  
> > \>\> what I've done looks to much complicated (better to do a whole rewrite!)  
> > \>\> - so: how would you do that (elegant!)  
> > \>\> Where (in which class) to put which methods?  
> > \>\> -three classes?? class1: Container for Lists, .new=\>List, methods  
> > list1+list2, list1==list2  
> > \>\> class2: Methods of list  
> > (List-Operations), methods: list1.name=...; list1.push el  
> > \>\> class3: ListElement +links, methods:  
> > Element.new, el1==el2  
> > \>\> class2+3 could be in one class, but list.new seems not to  
> > be compatible to element.new  
> > \>\> (both list.new\_element and list.new should be def  
> > initialize..., the get a new class-object!!)  
> > \>\> classes 1+2 could also be merged into 1 class  
> > (class+object-methods)  
> > \>\> BUT classes 1,2,3 can't be merged into one class -\> whats  
> > a nice elegant way to combine that all / how to "classify" it best?  
> > \>\>  
> > \>\>  
> > \>\> (wanted) RESULT:  
> > \>\>  
> > \>\> list1 = Lists.new(:listA, :double) # Lists: Storage for many lists  
> > \>\> # i would prefer: class DList \< Lists(type= :double); end; list1 =  
> > DList.new(:listA) # how to do that?  
> > \>\> list2 = Lists.new(:listB, :double)  
> > \>\> list2.details =\> {type: :double, name: :listB, count: 0 /\*Elements\*/  
> > }  
> > \>\> Lists.count # 2 (Lists)  
> > \>\>  
> > \>\> el1 = list1.new('abc')  
> > \>\> el2 = list1.new('def')  
> > \>\> el3 = ListA.new('ghi') # metaprogramming... # see below: #{Name}  
> > \>\>  
> > \>\> list1.count # 3 Elements  
> > \>\> list1.name # :listA  
> > \>\> list1 # ['abc','def','ghi']  
> > \>\> list1.map{|el| el } # ['abc','def','ghi']  
> > \>\> list1.find('def').previous # 'abc'  
> > \>\> list1.delete 'def'  
> > \>\> list3 = list(1) + list(2) ## Lists.count+=1, because of list3=... !  
> > ???  
> > \>\> list2.destroy # removes Elements and list  
> > \>\> Lists.count # 2  
> > \>\>  
> > \>\> thank you!  
> > \>\> ---- (my try / forget the rest:) ---  
> > \>\>  
> > \>\> class Lists  
> > \>\> @@allLists = {}  
> > \>\>  
> > \>\> def initialize(listname) # new list  
> > \>\> erg = # should be List.new !  
> > \>\> @@allLists[listname] = erg  
> > \>\> return erg  
> > \>\> end  
> > \>\>  
> > \>\> def delete(name)  
> > \>\> @@allLists -= @@allList[name]  
> > \>\> end  
> > \>\>  
> > \>\> def names  
> > \>\> @@allLists.keys  
> > \>\> end  
> > \>\> def count  
> > \>\> @@allLists.count  
> > \>\> end  
> > \>\>  
> > \>\> end  
> > \>\>  
> > \>\> class List  
> > \>\> def initialize(listname,type=:double) # new list(!)  
> > \>\> @name=listname  
> > \>\> @erg = # for example  
> > \>\> @@allLists[listname] \<\< erg  
> > \>\> return @erg  
> > \>\> end  
> > \>\>  
> > \>\> def type # :no, :single or :double # -chained list (:no=array)  
> > \>\> @type  
> > \>\> end  
> > \>\>  
> > \>\> def name=newname # Name of List =\> How can I then use  
> > #{Name}.new ?  
> > \>\> @name=newname  
> > \>\> end  
> > \>\> def name  
> > \>\> @name  
> > \>\> end  
> > \>\>  
> > \>\> def destroy # self  
> > \>\> Lists.delete self.name  
> > \>\> @erg.map{|el| el.destroy } # free it ??  
> > \>\> @erg = nil  
> > \>\> self.destroy # free self ??  
> > \>\> end  
> > \>\>  
> > \>\> def add\_new(obj) # Element!  
> > \>\> el = Element.new(obj)  
> > \>\> @erg[-1][1][1] = self # set "Pointer" in previous element to  
> > this one  
> > \>\> if self.type==:double then self[1][0] = @erg[-1] end # set prev  
> > ptr  
> > \>\> @erg \<\< el # add element to list  
> > \>\> end  
> > \>\>  
> > \>\> def push  
> > \>\> add\_new(obj)  
> > \>\> end  
> > \>\>  
> > \>\> def pop  
> > \>\>  
> > \>\> end  
> > \>\>  
> > \>\> def first  
> > \>\> @erg[0]  
> > \>\> end  
> > \>\>  
> > \>\> def last  
> > \>\> @erg[-1]  
> > \>\> end  
> > \>\>  
> > \>\> def insert\_at  
> > \>\> end  
> > \>\>  
> > \>\> def delete\_at  
> > \>\> end  
> > \>\>  
> > \>\> def next  
> > \>\> el.previous # ??? # call next from class Element  
> > \>\> end  
> > \>\>  
> > \>\> def previous  
> > \>\> el.next # ??? # class Element  
> > \>\> end  
> > \>\>  
> > \>\> @list\_pos=-1  
> > \>\> def each  
> > \>\> if @list\_pos\<@erg.length then  
> > \>\> @list\_pos+=1  
> > \>\> "return" @erg  
> > \>\> end  
> > \>\> ## @erg.each{|el| el ... } # how to return  
> > \>\> end  
> > \>\>  
> > \>\> def reset  
> > \>\> @list\_pos=-1  
> > \>\> end  
> > \>\>  
> > \>\> def count # of elements  
> > \>\> self.length  
> > \>\> end  
> > \>\> def remove\_element(pos)  
> > \>\> @erg[pos].delete # class Element  
> > \>\>  
> > \>\> end  
> > \>\>  
> > \>\> class Element  
> > \>\> def initialize(obj) # new element  
> > \>\> @erg = [obj,[previousEl,nextEl]]  
> > \>\> end  
> > \>\> def delete  
> > \>\> self=nil # how to destroy the whole instance?  
> > \>\> end  
> > \>\>  
> > \>\> def previousEl # of self  
> > \>\> @erg[1][0]  
> > \>\> end  
> > \>\>  
> > \>\> def nextEl # of self  
> > \>\> @erg[1][1]  
> > \>\> end  
> > \>\>  
> > \>\> end
> > 
> > Unsubscribe: \<mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe\>  
> > \<[http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt](http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt);
