Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
What is "better" is Ruby
class BaseClass
def items
#items ||= get_items
end
def get_items
raise NotImplementedError
end
end
class ClildClass < BaseClass
def get_items
# ... fetching items...
end
end
or simply
class BaseClass
def items
#items ||= get_items
end
end
class ClildClass < BaseClass
def get_items
# ... fetching items...
end
end
?
It's up to you. There is no right answer for this. You will simply get 2 different errors. First coince should be better if someone else will implement other ChildClasses, because they can see the "interface" they need to implement on their BaseClass.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Imagine I have an object "House". Inside the "House" I have want to have an object "Door" and an object "Window" with its different methods, lets say open and close doors/windows.
My main goal is to have code that looks like this:
my_house = House.new
neighbor_house = House.new
my_house.Door.open
neighbor_house.Window.close
neighbor_house.Door.open
neighbor_house.Door.close
my_house.Door.close
Though I do not understand, why you decided to ask this question here instead of reading some introduction to Ruby language, the answer follows:
class Door
def open; end
def close; end
end
class Window
def open; end
def close; end
end
class House
attr_reader :door, :window
def initialize door, window
#door, #window = door, window
end
end
house = House.new Door.new, Window.new
house.door.open
house.window.close
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Is it possible in Ruby to define such setters and getters for class that can be used with [] or () or smth alike? E.g.
word.meaning[:english] = "ruby"
puts word.meaning[:german] # "Rubin"
Note that word.meaning must not be a hash! and :english, :german are kind of additional parameters for setter/getter meaning.
Yes, it can be done. You need to define a []= and [] methods.
In this example, I am using a Hash as the internal data structure - you are free to use whatever you like.
class Word
attr_reader :meaning
def initialize
#meaning = Meaning.new
end
end
class Meaning
attr_reader :h
def initialize
#h = {}
end
def []=(key, value)
#h[key] = value
end
def [](key)
#h[key]
end
end
Example:
word = Word.new
word.meaning[:english] = 'Hello'
word.meaning[:english] # => 'Hello'
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Please help me implement class Repeat and it's methods:
class Repeat
def initialize(n)
#TODO
end
def each
#TODO
end
end
def n_times(n)
#TODO
end
This piece of code:
n_times(2) { |count| puts "You called me #{count} times" }
should return this result:
# You called me 1 times
# You called me 2 times
Welcome to StackOverflow. It seems like you are new to OOP and passing a block to a method in Ruby. This answer simplifies your question and just focuses on passing a block to a method. Here is some functioning code:
def n_times(n, &block)
n.times do |counter|
yield(counter + 1)
end
end
n_times(2) { |count| puts "You called me #{count} times" }
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Hi i have a code i would like to refactor
def gear_type
#gear_type ||= self.class.gear_types.find{|gears| gears["id"]==source["gear_type_id"]}["text"] if source["gear_type_id"]
end
def brand
#brand ||= self.class.brands.find{|node| node["id"]==source["brand_id"].to_s}["text"] if source['brand_id']
end
what is best way? to use eval or define method? i've tried this but there are some error i can't discover yet:
%w(gear_type brand).each do |meth|
define_method(meth){
instance_variable_get("##{meth}") rescue
instance_variable_set("##{meth}", self.class.send(meth.pluralize).find{|node| node["id"]==source["#{meth}_id"]}["text"]) if source["#{meth}_id"]
}
end
I'd just write a common finder method that you can parameterize:
def gear_type
#gear_type ||= generic_finder :gear_types, "gear_type_id"
end
def brand
#brand ||= generic_finder :brands, "brand_id"
end
def generic_finder(collection, primary_key)
self.class.send(collection).each do |object|
return object["text"] if object["id"] == source[primary_key]
end if source[primary_key]
nil
end
instance_variable_get("##{meth}") does not raise an error if the instance variable is not set, it returns nil. So you have to do almost the same you were doing:
%w(gear_type brand).each do |meth|
define_method(meth){
instance_variable_get("##{meth}") || instance_variable_set("##{meth}", self.class.send(meth.pluralize).find{|node| node["id"]==source["#{meth}_id"]}["text"]) if source["#{meth}_id"]
}
end
You should also refactor that line. It has to many stuff on it
%w(gear_type brand).each do |meth|
def source(meth)
#source ||= source["#{meth}_id"]
end
def class_meths(meth)
self.class.send(meth.pluralize)
end
def look_for(meth)
class_meths(meth).find{|node| node["id"] == source(meth)}["text"]
end
define_method(meth) do
value = instance_variable_get("##{meth}")
instance_variable_set("##{meth}", look_for(meth)) if !value && source(meth)
end
end
Here is a try. Not sure if it got better or not, but it's easier to read I think.
Oh! I just realized those methods probably won't be on the scope when the meta? method is called. But oh well, it's still a good example I think :)
It's probably cleaner just to use eval:
%w(gear_type brand).each do |meth|
eval <<-RUBY
def #{meth}
##{meth} ||= self.class.#{meth.plural}.find{|item| item["id"]==source["#{meth}_id"]}["text"] if source["#{meth}_id"]
end
RUBY
end
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to push an element to the end of this array and I get an error I don't understand.
main.rb:
require 'shop.rb'
so = Shop.new()
so.get(2)
so.get(1)
shop.rb
class Shop
def new()
#products = []
end
def get(product)
#products.push(product)
end
end
error:
NoMethodError: undefined method `push' for nil:NilClass
In Ruby, the constructor is initialize, not new. But you still use new to create an object, e.g. Checkout.new.
Also, the parentheses after method names are optional, and generally avoided in Ruby when there are no arguments.
def initialize
#items = []
end