Any experts in Ruby Class out there?

For general discussion related FlowStone
Post Reply
TimC
Posts: 9
Joined: Sat Dec 24, 2022 12:24 pm

Any experts in Ruby Class out there?

Post by TimC »

Hello all, and thanks in advance for any help! I've been trying to set up a Ruby Class that can handle and use its own internal arrays. I'm quite a novice at Ruby classes, and the nearest I've got is this:
class Destination
attr_accessor :l

@@letters

def initialize(l)
@l=l
end
### # out if clauses on first run...
@@letters=[] if @@letters==nil

def name
@@letters.collect{|ch| ch[0]}.join
end

def addLet(l)
@@letters << l
end

def wipe
@@letters.clear
end

end
I need in the class an array, @@letters (I'll eventually need other ones too). Line 3 sets up a variable called @@letters. LIne 7 turns it into an empty array. The ... if @@letters==nil... is to keep already inserted members of the array, but without line 3 it throws up an "uninitialised class variable" error - I have to run the class with the if statement #'ed out first time. Once that's done it works!
With the class now running I can do things like

@ylist=Destination.new("") a new instance of a Destination
%w[W A S H I N G T O N].each{|l| @ylist.addLet(l)} ... each letter becomes a member of @@letters
@ylist.name produces 'WASHINGTON'

It needs to be individual letters because I want to set up and access other data related to each letter. I'm sure there must be a better way to handle this, but so far it's eluded me.
tulamide
Posts: 2714
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Any experts in Ruby Class out there?

Post by tulamide »

You're using a class variable, not a class instance variable. Class variables also need to be initialized when created.

A class variable is shared among all classes and subclasses, even its own class construction. Try doubling your code:

Code: Select all

@ylist=Destination.new("")
%w[W A S H I N G T O N].each{|l| @ylist.addLet(l)}
@ylist.name # 'WASHINGTON'
@ylist=Destination.new("")
%w[W A S H I N G T O N].each{|l| @ylist.addLet(l)}
@ylist.name # 'WASHINGTONWASHINGTON'
Here's a general rule of validity (copy and paste to a RubyEdit):

Code: Select all

class Parent
  @@shared_among_everything = "class "
  @shared_among_parent = "parent"
  
  def self.shared_among_everything
    @@shared_among_everything
  end
  
  def self.shared_among_parent
    @shared_among_parent
  end
  
  def initialize(name)
    @specific_to_this_instance = name
  end
  
  def specific_to_this_instance
    @specific_to_this_instance
  end
end

class Child < Parent
  
end
    

show = []
show << Parent.class_variables
show << Parent.shared_among_everything
show << Parent.instance_variables
show << Parent.shared_among_parent

bob = Parent.new("Bob")

show << bob.instance_variables
show << bob.specific_to_this_instance
show << bob.shared_among_everything
show << bob.shared_among_parent

bobby = Child.new("Bobby")
show << bobby.instance_variables
show << bobby.specific_to_this_instance
show << bobby.shared_among_everything
show << bobby.shared_among_parent

watch "overview", show.flatten
"There lies the dog buried" (German saying translated literally)
Post Reply