Specify what folder to use for creating class object Ruby - ruby

I've got a small problem (maybe it isnt even a problem)
I am making an application in Ruby, and the folder/file structure goes something like this:
OrderSet/
..item.rb
..file.rb
..order_object.rb
OrderGet/
..item.rb
..files.rb
..order.rb
As you can see I got two item.rb files, they are both different in class structure. Now I need to create an OrderSet/item.rb object, how do I specify it needs to look in OrderSet and does not get the OrderGet one?
I have to make clear, all files are required in the main rb file.
I have tried doing OrderSet.Item (the class is called Item inside the item.rb) but it complains about an ininitialized constant OrderSet
Thanks in advance!
[edit]
I have also tried to make modules out of it, maybe I don't understand the concept correctly, but I have tried it with OrderSet.Item.new (OrderSet as module name)

You could use a module to create a namespace - that way each set of classes would be encapsulated to what they do (the folder name from your example). So classes in OrderSet would be wrapped in a module for example OrderSet/item.rb would become:
module OrderSet
class Item
# methods and properties
end
end
Then you could use it like
new_order_set = OrderSet::Item.new
RubyMonk has a lesson called Modules As Namespaces which has more details and examples you can run in your browser.

Related

ruby where to define structs

I know I can define new structs in ruby by doing
Person = Struct.new(:first_name, :last_name)
What I'm wondering is what is the appropriate place to define this struct (and other structs I'll be using). Person will be used throughout the system. In other languages such as Java, I would typically define Person as another class, but with this inline definition in Ruby, where is the correct place to define it so it is available to the entire system?
You can define it anywhere really. Just make sure to require the file wherever needed
EDIT
If you want some structure, it will be nice to have a folder where you define the structs and classes you need and require all files in that folder inside your app

Can I override Magento Varien classes?

I know how to override Mage classes (any class within app/code/core)
My question is how to override Varien classes? (classes within lib/Varien)
If I want to override Mage_Adminhtml_Block_Page_Menu
I create a class MyCompany_Adminhtml_Block_Page_Menu under app/code/local/MyCompany/Adminhtml/Block/Page/Menu.php
I name it like:
class MyCompany_Adminhtml_Block_Page_Menu extends Mage_Adminhtml_Block_Page_Menu
Now Magento uses my class MyCompany_Adminhtml_Block_Page_Menu instead of Mage_Adminhtml_Block_Page_Menu
My question is: where should I put the new class, and how to name it, to override, for example Varien_Date (lib/Varien/Date.php)
Thanks
If you must, copy the file and path to the local codepool and make the necessary changes. There is no configuration mapping to change the class name.
Explanation: see the bootstrapping in app/Mage.php. There is a load order set for the codepools and libraries in the following order:
app/code/local/
app/code/community/
app/code/core/
lib/
Typically, Varien_Autoload is responsible for mapping classnames such as Varien_Data_Collection_Db, Mage_Core_Model_Abstract, or Zend_Db_Select to relative filenames (Varien/Data/Collection/Db.php, Mage/Core/Model/Abstract.php, and Zend/Db/Select.php respectively). These file locations are then passed to include(), which internally uses the load order set in the bootstrap. Therefore, if the file Varien/Data/Collection/Db.php is present under one of the "earlier" locations, that version of the class definition will be used.
These type of modifications may be justified, but they should be well-considered and documented, as the entire definition will be owned by you and any upgrades will need to be merged in the future. It would be good to know what you would like to change, as someone else may have a slightly less invasive option.

How I can modularize Rails model?

I'm implementing several classes which does not have data by itself, just logics. These classes implements access control policy to date which depends on several parameters taken from data from other models.
I initially try to find answer to "Where to store such classes?" here, and the answer was apps/models directory. That's ok, but I like to clearly separate these classes from ActiveRecord inherited classes in hierarchy, both as file and class.
So, I created classes inside Logic module, like Logic::EvaluationLogic or Logic::PhaseLogic. I also wanted to have constants which passed between these logics. I prefer to place these constants into Logic module too. Thus, I implemented like this:
# in logic/phase_logic.rb
module Logic
PHASE_INITIAL = 0
PHASE_MIDDLE = 1000
class PhaseLogic
def self.some_phase_control_code
end
end
end
# in logic/evaluation_logic.rb
module Logic
class EvaluationLogic
def self.some_other_code
Logic::PhaseLogic.self.some_phase_control_code(Logic::PHASE_INITIAL)
end
end
end
Now, it work just fine with rspec (It passes tests I wrote without issues), but not with development server, since it can't find the Logic::PHASE_INITIAL constant.
I suspect it's related to the mismatch of the autoloading scheme of Rails and what I wanted to do. I tried to tweak rails, but no luck, ended-up with eliminating module Logic wrap.
Now the question I want to ask: How I can organize these classes with Rails?
I'm using 3.2.1 at this moment.
Posted a follow-up question "How I can organize namespace of classes in app/modules with rails?"
I am not sure whether I really understand your classes, but couldn't you create a Logic module or (I would rather do this:) PhaseLogic and EvaluationLogic objects in /lib directory?
It is not said that "Model" is always descendant of ActiveRecord. If the object belongs to "business logic" then it is a model. You can have models which do not touch database in any way. So, if your classes are "business objects", place them in 'app/models' and use like any other model.
Another question is whether you should use inheritance or modules - but I would rather think about including a module in PhaseLogic, and not about defining PhaseLogic in a module. Of course, all this depends heavily on the intended role of your objects.
Because in Ruby the class of object is not important, you do not need to use inheritance. If you want to 'plug' the logic objects into other objects, just take care that all '*Logic' classes have the required methods. I know that all I said is very vague, but I think I cannot give you some more concrete suggestions without knowing more about the role of these objects.
Ah, and one more thing!
If you find yourself fighting with Rails class autoloading, just use the old require "lib/logic.rb" in all the classes where you are using Logic::PHASE_INITIAL constants.
In this case I suppose that your problem was caused by different order of loading. The logic/evaluation_logic.rb has been loaded before logic/phase_logic.rb. The problem may disappear if you create logic.rb somewhere, where class autoloading can find it, and define these constants in that file.
Don't name your classes or modules Logic use specific names. Start with extracting logic into separate classes and then try to break them into smaller ones. Use namespaces to distinguish them from each other in lib folder, after this steps you would be able to extract some logic parts to separate gems and reduce codebase and complexity of application. Also take a look into presenter pattern.

How do I include two different headers that contain two different classes that have the same name?

I'm making some changes to an old MFC application. The header "stdafx.h" includes another header "mfcextensions.h" which defines a class "CMemDC". In another header I need to include "afxtoolbar.h" so that I can use the class "CMFCToolBar". The problem is, "afxtoolbar.h" will eventually include "memdc.h" which defines a class "CmemDC". The result is that understandably get compile error 2011.
Now I do have control over our existing code which defines "CMemDC" but this is used in a lot of places so I would rather not change it too much.
What is the best strategy for over coming this? I'm guessing that I could somehow use namespaces, or the other alternative is to rename our existing class "CMemDC" but this is more avoiding the problem rather than solving it for good.
Cheers
Using namespaces is the proper route but you probably also want to look at why CMemDC is declared throughout the whole app. Unless you really need your CMemDC declared everywhere you might be able to get away with removing the include from the stdafx.h and just including in the cpp files that really need it.
C++ namespaces might help you. Put at least one of the CMemDC classes in a suitable namespace, and use their fully qualified names where you want to use each one.
You can avoid using the fully qualified names, and make the namespace usage global in the current scope with
using namespace yournamespacename;
However, this is less explicit (in terms of not being able to directly see which CMemDC are you using at one point in the code) and in case you use both classes in the same scope this won't work.
If you have 2 classes with the same name your best option is to use namespaces. Also you can rename your class as well. But all of that is in your post already. So you have answered question yourself. There is no magic which can help you because you have stuck with the usual problem of the name clashing and namespaces were introduced to resolve this kind of problems.

No need to extend class/library in codeigniter

I would like to check if my assumption about codeigniter is right ?
We would normally extend a class when we are trying to include more functionality to the core, such as MY_Controller extends Controller, MY_Model extends Model etc...
But for example, if we are in the checkout library retrieving some checkout info(eg, product_id), we can just $this->load->library('product_lib',array('product_id'=>$product_id)) and we can easily $this->product_lib->product_name etc... from the checkout library right?
The $this->load thing is kind of equivalent to "hard code" checkout library to extend product_lib(class checkout_lib extends product_lib) to be able to use whatever methods/variables there is in the product_lib.
Please enlighten me.
In CodeIgniter $this->load is like having a resource manager (e.g. resourceManager->load("path/to/file")) and it takes care of loading the library, and passing any arguments you specify and such, easily allowing you to quickly get to using it.
So if you have a variable named product_name in your product_lib then yes calling $this->product_lib->product_name will be accessing that variable.
Really it just places the library into an array with the library name as the key and the instance of the library as the value so calling $this->product_lib is really calling something similar to $loadedLibraries['product_lib'] and returning the instance.
I hope that answers what you are asking, I'm quite tired and could have miss understood you question.
I think you misunderstood the OO paradigm and the way CI work.
$this->load is same with instantiate an object of the library/model, or load the helper file. CI have some sort of management to see if the helper/library/model already uploaded or not.
In other hand, the extends is used when defining a class, to tell PHP that the class will be inherit the parent class properties and method. A class is a blue print of object it will produce.
Maybe you can start by understanding the OO concept first. You can read this as a start, and see the reference used there.

Resources