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'
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 8 years ago.
Improve this question
Why in ruby, when you initiazlize a class do you set the instance variable equal to a variable of the same name?
def initialize(number)
#number = number
end
We do that so that newly-created object (not a class! with initialize and #vars, you initialize the object that was just created with new() method!) remembers the value of number.
Try using this one:
def initialize(number)
end
This gets a number, but does nothing with it. When this inializer ends, the object created will not remember what was the 'number'.
Here:
def initialize(number)
#foo = 5
#bar = number
end
the newly-created object will remember a 5 in #foo and the number in #bar.
The idea to name the #variable just like the parameter is just to make it easier. In the example above, it's hard to guess what the bar is about. Instead, if I rename the #bar into #number, it wil be obvious that it holds .. the number.
def initialize(number) def initialize(number)
#bar = number <-same thing-> #number = number
end just different name end
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 8 years ago.
Improve this question
I wanted to make a simple DSL where I could pass a bunch of methods to a block, relying on self as the implicit receiver. So basically here you can call the 'say' method on this class object, passing it 'things to say' as methods in the block. The last line returns ['Maria']. I was wondering if this is a good programming practice for creating DSLs and if there are any problems with this approach.
class SaySomething
def initialize
#said = []
end
def hey(name)
#said << name
end
def say(&block)
instance_eval(&block)
end
end
a = SaySomething.new
name = 'Maria'
a.say do
hey(name)
end
a.instance_eval { p #said } #=> produces ['Maria']
I would probably add an attr_accessor :said and then replace your last line with
a.said
#=> ['Maria']
Other than that your code looks fine to me. If you want to learn more about metaprogramming in Ruby, I can recommend the book "Eloquent Ruby".
The only problem with this approach is that any class variables will collide with variables in the same scope as the block. The usual approach is to provide instance evaluation, but also allow the user to specify the class as an argument as a fall back.
class Test
def test; "hello"; end
def say(&b)
if b.arity == 1
b.call(self)
else
instance_eval &b
end
end
end
t = Test.new
test = "fred"
t.say { p test } # "fred"
t.say { |t| p t.test } # "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
If I am editing the Array class, shouldn't I have to define each method with a self (e.g. self.sum). I'm not sure why this passes the rpsec tests for the 'Test-First' Ruby track without the self.method immediately following the def.
class Array
def sum
count = 0
self.each {|x| count += x}
count
end
def square
self.map {|x| x * x}
end
def square!
self.map! {|x| x * x}
end
end
These are "instance methods" - they operate on an instance of an Array, not the Array class itself. If you were to put self. before the name of each method when defining it, you would be defining a "class method", which wouldn't make any sense for these methods.
Although not necessary, the reason that self. works when invoking these methods from within the body of another one of the methods is that self is defined to be the "instance" at that point. This contrasts to when you're defining the methods with def, where self is the Array class.
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
How can I reference an object from a method without passing it as a variable?
I am getting error:
NameError: undefined local variable or method ‘my_object’ for Myclass:Class
class B
attr_accessor :somethings
include Enumerable
def initialize(*values)
self.somethings = []
end
end
my_object = B.new({d:'d'})
class Myclass
def self.my_method
p my_object
end
end
Run: Myclass.my_method
What I do NOT want to do for all my methods is...
def self.my_method(my_object)
p my_object
end
I could also solve the issue with use from a global variable
$my_object = B.new({d:'d'})
However, I only really want to make the variable available to my methods in Myclass class.
I only really want to make the variable available to my methods in Myclass class.
Then you should define it as an instance variable in corresponding scope of Myclass. As it is now, my_object is a local variable and is not visible because of the scope gate.
class Myclass
#my_object = B.new({d:'d'})
def self.my_method
p #my_object
end
end
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.