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.
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 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
I was wondering if something like this would be possible say we have
def call_something
yield a
end
where a is an undefined variable? Is this kind of thing possible and if so can you provide an example of how it can be useful?
I know you can pass arguments to yield but so far I know you can only pass actual arguments that have actual values.
To clarify, I meant something like this:
class A
def initialize
print "Enter a value: "
#a = gets.chomp
end
def m
yield #a
end
end
a = A.new
a.m do |x|
puts "You entered #{x}"
end
Where you could supply something and then pass a block using that 'something' as an argument.
Even if you could, I'm not sure it would make sense, as to use that value in the passed block you would have to assign it to an identifier:
call_something do |arg|
# you want `arg` to be the "unidentified" value
end
At that point, it's not the same "unidentified variable" you were talking about before, and the only way you can really represent it is as nil. So you may as well just pass nil in the first place
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