Add methods to an already-instantiated object? [duplicate] - ruby

This question already has answers here:
Add method to an instanced object
(8 answers)
Closed 3 years ago.
I know how to use include to add mixins to a class in Ruby. However, I want to add one or more methods to an already instantiated object. Is that possible?
For example, the Rack::File::Iterator class behaves as an iterator, but it doesn't inherit from Enumerable. This means that it doesn't come with a reduce method, even though it does contain an each method.
I'd like to add the reduce method to an already-instantiated Rack::File::Iterator object (which I'll refer to as "obj" here), so that I can just do the following ...
result = obj.reduce { |a,b| a + b }
If I could somehow include the Enumerable module into the already-instantiated obj, I think this would accomplish what I want.
I am only referring to Rack::File::Iterator as an example. I'm looking for a general solution which will work with instantiated objects of any class. Furthermore, I'm only using reduce as an example, as well. I want this to work with any methods I might wish to add to an object.
Yes, I know how to write my own reduce function to which I could pass obj and a block as parameters. However, I'd prefer to do this kind of dynamic include into an already-instantiated object, if possble.
Thank you in advance.
ADDENDUM
I went to the article referenced below (thank you!), and I then realized that there is yet another way to do this which was not mentioned in that article. Therefore, I added another answer to that article with the methodology that I thought of. Here it is, using the example I outlined above ...
class << obj
include Enumerable # or any other module
end
This adds all the methods from Enumerable into my object.

Yeah, it is possible.
Add method to an instanced object

Related

Extract information about method receiver from stack

If we call caller method, we get something like:
prog.rb:3:in `a'
prog.rb:6:in `b'
prog.rb:9:in `c'
This is helpful for humans, but if I wanted to analyze the stack programmatically, not really, as two methods called :a may be entirely unrelated.
Is there any way/method to extract information about the receiver of the methods (like its class or object id) as well? For example:
prog.rb:3:in `Klass#a'
prog.rb:6:in `Modoole#b'
prog.rb:9:in `OtherKlass#c'
Formatting is only an example; this info might be an Array or anything.
I'm trying to emulate this with TracePoint, but forming a separate stack is a bad solution. Is there any Ruby way I missed in the docs?
There's an alternative to Kernel#caller named Kernel#caller_locations, that returns an array of Thread::Backtrace::Location objects. According to the manual, these should in theory be able to give you this information through the #label method.
Returns the label of this frame.
Usually consists of method, class, module, etc names with decoration.
After trying this out however, I need to question the term usually in the docs, because it seems to only return the method name still. Unless usually means it works for you, there seems to be no way of accomplishing this as of now.
Edit:
As per comment, one case that satisfies the condition of usually is when the method call is coming from within a Class or Module body:
class A
def trace
puts caller_locations.first.label
end
end
class B
A.new.trace
end
#=> <class:B>
module C
A.new.trace
end
#=> <module:C>

On which object/class does DelegateClass and similar methods live?

Sorry for the poor title, but I'm a bit lost.
I'm trying to figure out on which object/class live methods such as DelegateClass and what is the term for these types of methods. I'm reading Metaprogramming Ruby and, in the book, these methods are generically called Mimic Methods, but searching the internet for this gives all kinds of results, so I'm wondering if there's a better name for them.
I've checked the source code of DelegateClass and I assumed that it was added to Object, but it's not there. I can see the the classes Delegator and SimpleDelegator, which are in the same rb file, are added as constants (although I'm not sure how they are added).
Thanks!
Just found the answer. It's a private method in Object
ruby-1.9.2-p290 :033 > Object.private_instance_methods(false).grep /Dele/
=> [:DelegateClass]
edit
I found out that what I needed to understand is What is the current class? in a given context.
Look closer at the file.
def DelegateClass(superclass)
klass = Class.new(Delegator)
...
and use
method(:DelegateClass).owner
to find the class where it sits. As mentioned in the comments private instance methods on Module contain anything defined on Object.
So no, DelegateClass() is not a special method in any way except for being called in uppercase (which makes it look like a constant). It just returns an anonymous class created on-the-spot that can be inherited from.

Do rubyists reference accessors from mixins?

Is it considered bad practice to reference accessors on the extended object from within a mixin method? A simplistic example:
module WindInstrument
def play
mouthpiece.blow #requires a mouthpiece
end
end
class Saxophone
attr_reader :mouthpiece
def initialize
#mouthpiece = Mouthpiece.new
end
include WindInstrument
end
Saxophone.new.play
In this case, I would actually just move the requirement for a mouthpiece directly to the WindInstrument module, but what about in a more complex scenario, where it really makes sense for the accessor to live on the extended object? Is this just an issue of an inappropriate separation of concerns?
Mixins feel useful for adding encapsulated behavior that doesn't require knowledge of the extended object's state. In fact, my gut tells me that a mixin shouldn't have knowledge of any state, whatsoever. If it needs knowledge of state, I would typically fall back to one of two choices:
Put the state in a class, and add it through composition, instead of through the inheritance hierarchy. My issue with this is that I know rubyists out there are creating mixins that access state, which makes for more readable, if less intuitive (to me) design.
Pass the mouthpiece as a parameter to the module. Even I can tell that this seems to muddy the design, and feels like an abomination in the ruby worldview.
Does this code bother anyone else? I know there are a lot of smart people using ruby out there, so I assume the problem is mine. What am I missing? Do I just need to chill out? What would you do?
I think it's the same as in monkey-patching: it's ok to do it, but you have to make sure that there are no alternatives first (ie. You can't modify the classes using your interface) and second, you must be very explicit about it (make sure that the docs, the comments and the interface mention that this our that method is required and will be invoked) and throw a useful error message if it isn't
Ruby's accessors are interfaces, not implementation.
For example, if you call person.height_in_feet=, you don't know what units the height is actually implemented in as an instance variable. It could be metres, feet, or cubits.
One real-life example of mixins using an accessor is the Enumerable module. Although I don't include this module in any classes I create, I'm happy with what it does. It gives you convenient methods like map and each_with_index, while staying DRY - there's only one implementation of what objects you'd access with all of the methods of the "mixee", and there's only one definition of what map does, for any object that uses Enumerable.

Ruby - Array method confusion

we can call the Array method in the top level like this
Array(something)
that makes sense to me, it's a method call without explicit receiver, and self, which is main in this case, is inserted at the front of the method call. But isn't it that this is equivalent to :
Kernel.Array(something)
this doesn't make sense to me. Since in the first case, the object main is of class Object, which got Kernel module mixed in, thus have the Array method. But in the second case, we are calling the Array method on the Kernel module object itself, rather than main object, didn't they are NOT the same thing?
sorry for my bad english.
Kernel.Array is what is known as a module function. Other examples of module functions include Math.sin, and Math.hypot and so on.
A module function is a method that is both a class method on the module and also a private instance method. When you invoke Array() at the top-level you are invoking it as a private instance method of the main object. When you invoke it through Kernel.Array() you are invoking it as a class method on Kernel. They are the same method.
To learn more, read up on the module_function method in rubydocs: http://www.ruby-doc.org/core/classes/Module.html#M001642
class Object mixed-in module Kernel, but Kernel is an instance of Object. So Kernel "module" methods - is it's instance methods.
What's confusing you is the difference between class and instance methods.
Class methods don't have an explicit receiver, and thus no self to access other fields with. They just... are.
Generally instance methods are used to query or manipulate the attributes of a given object, whereas the class methods are "helper" or "factory" methods that provide some functionality associated with or especially useful for a certain kind of class, but not dependent on actual live instances (objects) of that class.
Not sure about Ruby, but Java has (for example) a whole class, Math that contains nothing but instance methods like sin(), max(), exp() and so forth: There is no "Math" object, these are just methods that embody mathematical algorithms. Not the best example, because in Ruby those methods are probably embedded right into the numeric classes as instance methods.
The case you mention is a bit confusing because Array's () method and Kernel's Array() method are in fact different methods that do similar things. Both are class methods.
Array() takes a list of arguments and makes and returns an array containing them.
Kernel.Array() takes a single argument of an "array-able" type, such as a sequence, and takes the values returned by this argument and builds an array from those.
UPDATE
The downvote was perhaps justified; I apologize for taking on a subject outside my area of expertise. I think I'll be deleting this answer soon.
# Chuck: I would sincerely hope that a language/library's official documentation would offer some meaningful clues as to how it works. This is what I consulted in answering this question.
The rdoc for Kernel.Array():
Returns arg as an Array. First tries to call arg.to_ary, then arg.to_a. If both fail, creates a single element array containing arg (unless arg is nil).
for Array.():
Returns a new array populated with the given objects.
I don't know about you, but I think if the docs vary that much then either they're talking about separate methods or the documentation is a train wreck.
# freeknight:
But everything in ruby is an object of some kind, even classes and modules. And Kernel.Array is actually a method call on an specific object - the Kernel object.
Yeah, under the covers it's similar in Java too. But the Array() method isn't doing anything with Kernel, any more than Array() is doing anything with the Array class object, so this is really only a semantic quibble. It's an instance method because you could hang it off class IPSocket if you were crazy enough, and it would still work the same way.
They are the same thing:
a = Kernel.Array('aa')
=> ["aa"]
a.class
=> Array
a = Array('aaa')
=> ["aaa"]
a.class
=> Array
Maybe there is an alias?

What are some good examples of Mixins and or Traits?

I was reading up on Ruby, and learned about its mixins pattern, but couldn't think of many useful mixin functionality (because I'm not used to thinking that way most likely). So I was wondering what would be good examples of useful Mixin functionality?
Thanks
Edit: A bit of background. I'm Coming from C++, and other Object languages, but my doubt here is that Ruby says it's not inheriting mixins, but I keep seeing mixins as Multiple inheritance, so I fear I'm trying to categorize them too soon into my comfort zone, and not really grok what a mixin is.
They are usually used to add some form of standard functionality to a class, without having to redefine it all. You can probably think of them a bit like interfaces in Java, but instead of just defining a list of methods that need to be implemented, many of them will actually be implemented by including the module.
There are a few examples in the standard library:
Singleton - A module that can be mixed into any class to make it a singleton. The initialize method is made private, and an instance method added, which ensures that there is only ever one instance of that class in your application.
Comparable - If you include this module in a class, defining the <=> method, which compares the current instance with another object and says which is greater, is enough to provide <, <=, ==, >=, >, and between? methods.
Enumerable - By mixing in this module, and defining an each method, you get support for all the other related methods such as collect, inject, select, and reject. If it's also got the <=> method, then it will also support sort, min, and max.
DataMapper is also an interesting example of what can be done with a simple include statement, taking a standard class, and adding the ability to persist it to a data store.
Well the usual example I think is Persistence
module Persistence
def load sFileName
puts "load code to read #{sFileName} contents into my_data"
end
def save sFileName
puts "Uber code to persist #{#my_data} to #{sFileName}"
end
end
class BrandNewClass
include Persistence
attr :my_data
def data=(someData)
#my_data = someData
end
end
b = BrandNewClass.new
b.data = "My pwd"
b.save "MyFile.secret"
b.load "MyFile.secret"
Imagine the module is written by a Ruby ninja, which persists the state of your class to a file.
Now suppose I write a brand new class, I can reuse the functionality of persistence by mixing it in by saying include ModuleILike. You can even include modules at runtime. I get load and save methods for free by just mixing it in. These methods are just like the ones that you wrote yourself for your class. Code/Behavior/Functionality-reuse without inheritance!
So what you're doing is including methods to the method table for your class (not literally correct but close).
In ruby, the reason that Mixins aren't multiple-inheritance is that combining mixin methods is a one time thing. This wouldn't be such a big issue, except that Ruby's modules and classes are open to modification. This means that if you mixin a module to your class, then add a method to the module, the method will not be available to your class; where if you did it in the opposite order, it would.
It's like ordering an ice-cream cone. If you get chocolate sprinkles and toffee bits as your mixins, and walk away with your cone, what kind of ice cream cone you have won't change if someone adds multicolored sprinkles to the chocolate sprinkles bin back at the ice-cream shop. Your class, the ice cream cone, isn't modified when the mixin module, the bin of sprinkles is. The next person to use that mixin module will see the changes.
When you include a module in ruby, it calls Module#append_features on that module, which add a copy of that module's methods to the includer one time.
Multiple inheritance, as I understand it, is more like delegation. If your class doesn't know how to do something, it asks its parents. In an open-class environment, a class's parents may have been modified after the class was created.
It's like a RL parent-child relationship. Your mother might have learned how to juggle after you were born, but if someone asks you to juggle and you ask her to either: show you how (copy it when you need it) or do it for you (pure delegation), then she'll be able at that point, even though you were created before her ability to juggle was.
It's possible that you could modify a ruby module 'include' to act more like multiple inheritance by modifying Module#append_features to keep a list of includers, and then to update them using the method_added callback, but this would be a big shift from standard Ruby, and could cause major issues when working with others code. You might be better creating a Module#inherit method that called include and handled delegation as well.
As for a real world example, Enumerable is awesome. If you define #each and include Enumerable in your class, then that gives you access to a whole host of iterators, without you having to code each and every one.
It is largely used as one might use multiple inheritance in C++ or implementing interfaces in Java/C#. I'm not sure where your experience lies, but if you have done those things before, mixins are how you would do them in Ruby. It's a systemized way of injecting functionality into classes.

Resources