Recognizing an array of constructor - ruby

What can I do to recognize an array which is declared in a constructor, by method, in this class?
I received an error:
undefined local variable or method 'myArray'
class Calc
def initialize()
myArray = []
end
def add4ToArray()
myArray.push(4)
puts myArray.size
end
end
obj1 = Calc.new
obj1.add4ToArray()

You need to declare it as an instance variable as opposed to a local variable. In the constructor, use #myarray = [].

Related

kind of instance variable changed in method

class Appthin
#fileDir = ["a","b"]
puts #fileDir.class
def findclass
puts #fileDir.class
checkFiles(#fileDir)
end
end
input
Array
NilClass
why they are different, it confused me.
This is because variables starting with an # symbol are instance variables, but when you're first calling it, there isn't an instance of Appthin initialized.
When you refer to an instance variable, it selects self and sets an instance variable for that.
If you're calling an instance variable from the body of your class, then self is the class itself, which is an instance of Class, but not an instance of Appthin.
The solution to your problem depends on what you're trying to do:
If you want to set a variable in the class body, which is accessible to all instances of the class, I'd use a constant.
class Appthin
FILE_DIR = ['a', 'b']
def find_class
puts FILE_DIR
end
end
If you're trying to set a variable belonging to a specific instance of Appthin, which can then be changed, set it in the initialize method:
class Appthin
def initialize
#file_dir = ['a', 'b']
end
def find_class
puts #file_dir
end
end

How to Initialize Class Arrays in Ruby

I want to create an empty array as a class instance variable in Ruby. However, my current method does not seem to work.
Here is my code:
class Something
#something = []
def dosomething
s = 5
#something << s
end
end
When I call the function, it gives me an undefined method traceback.
However, if I do something similar with class variables, i.e.:
class Something
##something = []
def dosomething
s = 5
##something << s
end
end
This works perfectly.
I know I can use the initialize method to actually create an empty list for #something, but is there another way of doing this without using the initialize method? And why does this work for class variables?
EDIT: Fixed typo
You need to use initialize as a constructor as below code and is there any reason why not to use initialize/constructor. And please fix a typo error in class definition Class Something to class Something no camel case or first letter capitalize while in class
class Something
def initialize
#something = Array.new
end
def dosomething
s = 5
#something << s
end
end
class variable ## are available to the whole class scope. so they are working in the code and if you want to use instance variable # you need to initialize it as above. The instance variable is share with instance/objects of a class
for more details visit the link Ruby initialize method
At first you have a typo. Change Classto class. Next I suggest to use the initialize method. While creating a new object this is the perfect place to initialize instance variables.
class Something
##my_class_variable = [1]
def initialize
#something = []
end
def dosomething
s = 5
#something << s
end
def self.get_my_class_variable
##my_class_variable
end
end
Your script will be read and executed from top to bottom and after this,
you can access the class Something. While the parser reads your script/class/module you can define class variables (##), execute mixins and extend the class with other modules. This is why you can define a class variable, but you can not define an instance variable. Because actually you have no instance object from your class. You only have a class object. In ruby everything is an object. And your class object has a defined class variable now:
Something.get_my_class_variable
# => [1]
Now you can create an instance from your class. With Something.new the initialize method will be invoked and your instance variable will be defined.
something = Something.new
something.dosomething
# => [5]
Later, if you are familar with this you can define getter and setter methods with attr_reader, attr_writer and attr_accessor for instance objects or cattr_reader, cattr_writer and cattr_accessor for class objects. For example:
class Something
attr_reader :my_something
def initialize
#my_something = []
end
def dosomething
s = 5
#my_something << s
end
end
something = Something.new
something.my_something
# => []
something.dosomething
# => [5]
something.my_something
# => [5]
Your problem in trying to access #something in your instance method is that, in the scope of instance methods, # variables refer to instance variables, and your #something is a class instance variable.
# variables are instance variables of the instance that is self when they are created. When #something was created, self was the class Something, not an instance of Something, which would be the case inside an instance method.
How then to access a class instance variable in an instance method? Like regular instance variables, this must be done via a method, as in attr_accessor. One way to do this is to use class << self to tell the Ruby interpreter that the enclosed code should be evaluated with the class (and not the instance) as self:
class C
#foo = 'hello'
class << self
attr_accessor :foo # this will be a class method
end
def test_foo # this is, of course, an instance method
puts self.class.foo # or puts C.foo
end
end
We can show that this works in irb:
2.3.0 :005 > C.foo
=> "hello"
2.3.0 :006 > C.new.test_foo
hello
You have correctly created a class instance variable, #something, and initialized it to an empty array. There are two ways for instances to obtain or change the value of that variable. One is to use the methods Object#instance_variable_get and Object#instance_variable_set (invoked on the class):
class Something
#something = []
def dosomething
s = 5
self.class.instance_variable_get(:#something) << s
end
end
sthg = Something.new
sthg.dosomething
Something.instance_variable_get(:#something)
#=> 5
The other way is to create an accessor for the variable. There are several ways to do that. My preference is the following:
Something.singleton_class.send(:attr_accessor, :something)
Something.something #=> [5]
In your dosomething method you would write:
self.class.something << s

Ruby: Why is an instance variable defined inside a class nil?

class Something
#b = [4432]
def screen
puts #b.class
end
end
s = Something.new
s.screen
outputs 'Nilclass'. Was wondering, why does an instance variable which is defined inside a class always part of NilClass?
Instance variables belong to an object (aka an instance), that's why they are called instance variables. Every instance has its own instance variables.
In your case, there are two objects: Something (which is an instance of Class) and s (which is an instance of Something). Each of those two objects has its own set of instance variables. Something has an instance variable called #b which points to [4432]. s has no instance variable named #b because you never assign to it, and uninitialized instance variables evaluate to nil.
You need to set it like this:
class Something
def initialize
#b = [4432]
end
def screen
puts #b.class
end
end
The way you did it, the variable belongs to Something class itself, not its instance. Observe:
class Something
#b = [4432]
end
s = Something.new
s.instance_variable_get(:#b) # => nil # !> instance variable #b not initialized
Something.instance_variable_get(:#b) # => [4432]
Generally the instance variable must be defined inside the constructor whereas in ruby the default constructor is initialize the syntax is
def initialize
end #these is the default constructor in ruby
so when we define the insatnce variable inside the constructor and when we create the instance of a class then that instance/object will contain the copy of instance variables
most important thing is that though the instance/object contains the instance variable the instance/object cannot access it why because by default the instance data is private so in order to access it we need to define the getters and setter for those instance variable
class Something
attr_accessor:b
def initialize
#b = [4432]
end
s=Something.new
puts"#{s.b}"
Because the variable #b does not exist!. For e.g. the following would produce the same results you see.
class Something
#b = [4432]
def screen
puts #a.class #=> note #a which is non-existent
end
end
s = Something.new
s.screen
Whereas
class Something
#b = [4432]
def screen
puts #a.class
end
def self.screen
puts #b.class
end
end
s = Something.new
s.screen #=> NilClass
Something.screen #=> Array
if you initialize #b outside the initializer, you want #b scope to be a class variable, so you have to call it ##b :
##b has the same value for all Instance of your Something Class
like :
class Somthing
##b = [4432]
def initialize
#[...]
end
def screen
puts ##b.class
end
end
#Jörg W Mittag answer is correct. I just wont to add, that defining an instance variable in class != defining instance variable in an instance of that class. To create an instance variable, in your case in s instance you need to add an initialize method witch gets triggered when new method is called on a class.
def initialize(b_value = default_value)
#b = b_value
end

Why can't I append an array?

I want to add user input to an array if it's a palindrome. I keep getting:
undefined method `<<' for nil:NilClass
when I run it.
Eventually I want to compare all values and find the highest, that is why I have the class in there.
class Palindrome
attr_accessor :palindrome_array
#palindrome_array = []
def check_palindromic(variable)
if variable.reverse == variable
#palindrome_array << variable
end
end
end
a = Palindrome.new
puts "Enter a number"
i = gets.chomp()
a.check_palindromic(i)
I have been scratching my head over this. Can someone tell me what is missing?
Because your object a didn't have the instance variable #palindrome_array, that you think it has. You need to do this:
a = Palindrome.new
a.palindrome_array=[]
puts "Enter a number"
i = gets.chomp()
a.check_palindromic(i)
Remove #palindrome_array = [] from the this code as it has different meaning:
class Palindrome
attr_accessor :palindrome_array
#palindrome_array = []
Here is additional explanation:
class Palindrome
attr_accessor :palindrome_array
#palindrome_array = []
def check_palindromic(variable)
if variable.reverse == variable
#palindrome_array << variable
end
end
end
a = Palindrome.new
Palindrome.instance_variables # => [:#palindrome_array]
a.instance_variables # => []
a.palindrome_array=[]
a.instance_variables # => [:#palindrome_array]
I keep getting "undefined method `<<' for nil:NilClass" when I run it.
Humm. This happens because #palindrome_array defined below class Palindrome is an instance variable belonging to the class object. Note this is not the same as a class variable and could not be referred to as ##palindrome_array, whereas #palindrome_array defined inside the check_palindromic method is an instance variable belonging to instances of Palindrome. They are two distinct variables and the first is accessible only in a class method.
You need to initialize all instance variables in your classes constructor:
class Palindrome
...
def initialize
#palindome_array = []
end
...
end
The way you have it currently, you are declaring an instance variable at the class level (which works because all classes inherit from Class)

Can I initialize a class variable using a global variable? (ruby)

Do I have create extra method for this kind of assignment? ##variable = #global_variable Why? I want to have some variables that hold values and definitions to be accessible all through my script and have only one place of definition.
#global_variable = 'test'
class Test
##variable = #global_variable
def self.display
puts ##variable
end
end
Test.display #gives nil
In Ruby, global variables are prefixed with a $, not a #.
$global = 123
class Foo
##var = $global
def self.display
puts ##var
end
end
Foo.display
correctly outputs 123.
What you've done is assign an instance variable to the Module or Object class (not sure which); that instance variable is not in scope of the class you've defined.

Resources