Class like Struct - ruby

I have task here: I must create a class which will be like class Struct. I have just started to learn Ruby and don't know how to create it. In my attempts, I was able to create a method that takes arguments and creates an array. Then I have to go through the array and all of the arguments, make the argument class, in which I can bring some value. But I don't know how to create methods that can create classes in Ruby.
I am asking for help if you have an example or know where to find it, I will be grateful!
my attempts:
class Hobbit
def new(*params)
"#{params.inspect}"
end
end

So I assume all you want is
And what i want it is an example of a method that can create classes
Check out this question and the accepted answer which shows you how to create a class dynamically given a class name. Let me know if that's what you're looking for.

Related

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

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

Ruby: provide real world examples when have you opened objects eigenclass and changed it

Coming from C# world I am used to thinking classes are immutable definitions of objects and that every object has fixed class.
I am trying to open my mind to possibilities of using
class << some_object
def something_unique_to_this_object
# code
end
end
I am not talking about class << self.
I am talking about changing one or several object's class definition, but not all of them like class << self does.
In several months or almost a year of using ruby I have never found a situation when I thought oh good I can open this objects eigenclass and change it and leave majority of other objects of same class unchanged. Please provide real world examples when you used this.
You say "not like class << self". Well, guess what - class/module methods are implemented exactly this way. There is a reason for the similarity in syntax. self inside a class definition refers to the class itself. Any class/module methods that you define are actually methods of the eigenclass of that class/module. Your specific class is just one instance of the class Class.
For other examples, look at something like rspec. How would you implement a double and add some methods to it dynamically? How would you stub a method of an existing object? Eingenclasses are an easy and perfect fit for it.
Other than more meta uses, I also sometimes find it comfortable while debugging. Like I can put a breakpoint, alter the behaviour of some object and continue after the breakpoint to see what happens. You might not want to affect all objects of that class or the object might be an instance of an anonymous class.

can I use an instance method in ruby to create another object in ruby?

I have the an instance method of the class Schedule:
However, I would like one of the methods create_recurring to create an object of class Orchestrate.
The reason why is that I wanted all classes of Orchestrate to be what creates something in the actual database. That class has all the methods to actually create something.
So it looks like this:
def create_recurring
orchestrate = OrchestrateIo.new(#bot_client_id, :profiles)
end
However, when writing my rspec, I had no idea how to actually test for the creation of another object, which made me think I was going about it all wrong.
questions:
1) Is this doable/allowable?
2) If yes, how would I test for the creation of a new instance of another Class?
3) What's the right way to do it if this approach is wrong?
1) Of course it is doable. It is the core of the factory pattern.
2) something like this? (not 100% sure about your code structure, so...)
it "makes an OrchestrateIo" do
Orchestrate.create_recurring.should be_an_instance_of(OrchestrateIo)
end
3) It's not wrong. It may or may not be appropriate for what you are doing, but there is not enough context to the question (or I am not smart enough) for me to figure out if it is, or not.

Ruby: instantiate objects from files

Overview:
main.rb
items/
one.rb
two.rb
three.rb
Every file in items/ should have a human readable description (serialization is out), like so (but maybe a DSL would be better?):
class One < BaseItem
name "Item one"
def meth
"something"
end
main.rb should be able to instantiate all objects from the items/ directory. How could this be accomplished? Not familiar with Ruby, I see the object model allows for some pretty cool things (those class hooks, etc), but I'm having trouble finding a way to solve this.
Any input way appreciated.
EDIT:
Shoot, I may have missed the gist of it - what I didn't mention was the stuff in the items/ dir would be dynamic — treat items as plugins, I'd want main.rb to autodetect everything in that dir at runtime (possibly force a reload during execution). main.rb has no prior knowledge of the objects in there, it just knows what methods to expect from them.
I've looked at building DSLs, considering defining (in main.rb) a spawn function that takes a block. A sample file in items/ would look something like:
spawn do
name "Item name"
def foo
"!"
end
end
And the innards of spawn would create a new object of the base type and pass the block to instance_eval. That meant I'd need to have a method name to set the value, but incidentally, I also wanted the value to be accessible under name, so I had to go around it renaming the attr.
I've also tried the inherit route: make every item file contain a class that inherits from a BaseItem of sorts, and hook into it via inherited ... but that didn't work (the hook never fired, I've lost the code now).
EDIT2:
You could look at what homebrew does with its formulas, that's very close to what I'd want - I just didn't have the ruby prowess to reverse engineer how it handles a formula.
It all boils down to requiring those files, and make sure that you implemented the functionality you want in them.
If you want a more specific response, you need to ask a more specific question.
I am no expert on object persistence, but answer to your specific question is, that you have 2 good choices: One is YAML, and the other is Ruby itself: a DSL written by you or someone else, and specific to your business logic.
But I think that more general answer would require reviewing object persistance in Ruby more systematically. For example, ActiveRecord::Base descendants persists as database tables. There are other ways, I found eg. this http://stone.rubyforge.org/ by googling. This is my problem as well, I'm facing the same question as you in my work.
What you are asking for looks and smells a lot like a normal Ruby script.
class One < BaseItem
name "Item one"
def meth
"something"
end
We'd close the class definition with another end statement. name "Item one" would probably be done inside the initialize method, by setting an instance variable:
attr_reader :name
def initialize(name)
#name = name
end
Typically we wouldn't call the folder "items", but instead it would be "lib", but otherwise what you are talking about is very normal and expected.
Instantiating all items in a folder is easily done by iterating over the folder's contents, requiring the files, and calling the new method for that item. You can figure out the name by mapping the filename to the class name, or by initializing an instance at the end of the file:
one = One.new("item one")
You could keep track of the items loaded in an array or hash, or just hardwire them in. It's up to you, since this is your code.
It sounds like you haven't tried writing any Ruby scripts, otherwise you would have found this out already. Normal Ruby programming books/documentation would have covered this. As is, the question is akin to premature optimization, and working with the language would have given you the answer.

How can I delegate calls to a method to another method in Ruby?

I want to create another name for a method that already exists, e.g. I want to call slice with only. I don't want to change anything about the behavior of that original method, so it's not a redefinition, but delegation. How can I do that?
There are a number of ways to do that in Ruby. Please check this post which may help you find your most suitable way of doing it.
http://gdakram.com/past/2010/12/2/multiple_ways_in_implementing_delegation_pattern_in_ruby/
class Whatever
def slice
# do something
end
alias :only :slice
end

Resources