Using a "?" when initialising an instance variable - ruby

I am trying to have sushiable? return an instance variable set in initialise but I can't seem to get it to work. What am I doing wrong?
attr_accessor :weight, :value, :sushiable?
def initialize (weight,value, sushiable?)
#weight = weight
#value = value
#sushiable = sushiable?
end
# def sushiable?
# false
# end

Using ? is only valid for methods names, not for variables. So, the correct way would be:
attr_accessor :weight, :value, :sushiable
def initialize (weight, value, sushiable)
#weight = weight
#value = value
#sushiable = sushiable
end
def sushiable?
sushiable
end

Related

Ruby error when creating new object: wrong number of arguments (given 5, expected 0)

I am learning Ruby but I am currently stuck here when trying to create a new object inside a method from another class. I have this main 'command.rb' class where I just initialize its arguments:
class Command
attr_accessor :key, :flag, :time, :bytes, :value,
def initialize(key, flag, expTime, bytes,value)
#key = key
#flag = flag
#expTime = expTime
#bytes = bytes
#value = value
end
end
Then I try to create a Command object inside this other class:
require_relative 'command'
class CommandDAO
def initialize
#data_hash = Hash.new
end
def set(arrayInfo, value)
full_key = Command.new(arrayInfo[1],arrayInfo[2],arrayInfo[3],arrayInfo[4],value)
data_hash.store(key,full_key)
return "STORED\r\n"
end
end
The error I am getting at the moment is that the expect number of values is 0. Why is this?
Thanks a lot for your help!!
Remove the comma after value
attr_accessor :key, :flag, :time, :bytes, :value,
It causes your initializer body to be regenerated/overwritten by attr_accessor

How to Make a Ruby Class act Like a Hash with Setter

For academic reasons, I'd like to make an instance of Ruby class act like a hash.
GOALS
Initialize MyClass instance with a hash # success
Request values from instance of myClass, like a hash # success
Then set properties as a hash # fail
Although some discussion exists, I tried what's out there (1, 2) with no success. Let me know what I'm doing wrong. Thanks!
class MyClass
attr_accessor :my_hash
def initialize(hash={})
#my_hash = hash
end
def [](key)
my_hash[key]
end
def set_prop(key, value)
myhash[key] = value
end
end
test = myClass.new({:a => 3}) #=> #<MyClass:0x007f96ca943898 #my_hash={:a=>3}>
test[:a] #=> 3
test[:b] = 4 #=> NameError: undefined local variable or method `myhash' for #<MyClass:0x007f96ca9d0ef0 #my_hash={:a=>3}>
You declared set_prop, but you're using []= in tests. Did you mean to get this?
class MyClass
attr_accessor :my_hash
def initialize(hash={})
#my_hash = hash
end
def [](key)
my_hash[key]
end
def []=(key, value)
my_hash[key] = value
end
end
test = MyClass.new({:a => 3}) # success
test[:a] # success
test[:b] = 4 # success
test.my_hash # => {:a=>3, :b=>4}
module HashizeModel
def [](key)
sym_key = to_sym_key(key)
self.instance_variable_get(sym_key)
end
def []=(key, value)
sym_key = to_sym_key(key)
self.instance_variable_set(sym_key, value)
end
private
def to_sym_key(key)
if key.is_a? Symbol
return ('#'+key.to_s).to_sym
else
return ('#'+key.to_s.delete('#')).to_sym
end
end
end
You should write it as test = MyClass.new({:a => 3}) and the below code should work.
class MyClass
attr_accessor :my_hash
def initialize(hash={})
#my_hash = hash
end
def [](key)
#my_hash[key]
end
def []=(key,val)
#my_hash[key]=val
end
def set_prop(key, value)
#myhash[key] = value
end
end
test = MyClass.new({:a => 3})
test[:a]
test[:b]= 4
test.my_hash # => {:a=>3, :b=>4}

Set instance variable

If I have a specific value assigned to an instance variable, how do I define a method to reassign the value of this variable? When I run the code below in rspec, I keep getting the original value.
class Test
def name
#name = 'me'
end
def name=(input)
#name = input
end
end
def name
#name = 'me'
end
Every time you call the method above, you set #name to 'me' and return it.
I believe you are looking for the ||= operator
def name
#name ||= 'me' # only set #name to 'me' if it is not already set
end
IMO, the best way to accomplish a default value for #name is:
class Test
attr_accessor :name
def initialize
#name = 'me'
end
end
example:
t = Test.new
t.name
# => "me"
t.name = 'foo'
# => "foo"
t.name
# => "foo"
Because you're setting the #name variable in the getter, where you should only be returning it. Like so:
class Test
def name
#name
end
def name=(input)
#name = input
end
end
Or more simply you should just use the attr_accessor method to declare boilerplate versions of the getter and setter methods. Like so:
class Test
attr_accessor :name
end
The initial value should be set in the constructor method.
class Test
def initialize
#name = 'me'
end
def name
#name
end
def name=(input)
#name = input
end
end
And you could use attr_accessor to make you code simple:
class Test
attr_accessor :name
def initialize
#name = 'me'
end
end

Why doesn't this method initialize the variables shown?

I get nil, nil but I expected the result to be 9, 'My Soduko'
class Soduko
attr_accessor :name, :rows, :columns
def initialize
rows = 9
columns = 9
name = 'My Soduko'
end
end
new_soduko= Soduko.new
puts new_soduko.rows
puts new_soduko.name
$ ruby soduko.rb
nil
nil
I thought new would use the initialize method and set those attributes?
What you need is an instance variable in the initialize method. You create an instance variable by prefixing the name with #. When you make a new Soduko object with new_soduko= Soduko.new you want to set instance variables for that particular object. Without the # you have just created local variables in the initialize method.
class Soduko
attr_accessor :name, :rows, :columns
def initialize
#rows = 9 # adding # makes these instance variables.
#columns = 9
#name = 'My Soduko'
end
end
new_soduko= Soduko.new
puts new_soduko.rows
puts new_soduko.name

Setting a dynamic field in Ohm / Redis

How do I set a field dynamically for a Ohm object?
class OhmObj < Ohm::Model
attribute :foo
attribute :bar
attribute :baz
def add att, val
self[att] = val
end
end
class OtherObj
def initialize
#ohm_obj = OhmObj.create
end
def set att, val
#ohm_obj[att] = val #doesn't work
#ohm_obj.add(att, val) #doesn't work
end
end
The attribute class method from Ohm::Model defines accessor and mutator methods for the named attribute:
def self.attribute(name)
define_method(name) do
read_local(name)
end
define_method(:"#{name}=") do |value|
write_local(name, value)
end
attributes << name unless attributes.include?(name)
end
So when you say attribute :foo, you get these methods for free:
def foo # Returns the value of foo.
def foo=(value) # Assigns a value to foo.
You could use send to call the mutator method like this:
#ohm_obj.send((att + '=').to_sym, val)
If you really want to say #ohm_obj[att] = val then you could add something like the following to your OhmObj class:
def []=(att, value)
send((att + '=').to_sym, val)
end
And you'd probably want the accessor version as well to maintain symmetry:
def [](att)
send(att.to_sym)
end
[] and []= as a dynamic attribute accessor and mutator are defined by default in Ohm::Model in Ohm 0.2.

Resources