And How you Benefit
To quote Matz, the creator of Ruby, ‘It’s kinda complex. Ruby is simple in appearance, but is very complex inside, just like our human body.’
I’m a serial entrepreneur and generally have a few projects on the go. Obviously I prefer Ruby, but another project I have running is integrating a Ruby application with the Salesforce platform. Where possible, logic is executed in the Ruby application and sync’d to the Salesforce database.
But, I was confronted with the need, and a little bit of curiosity - how would I execute this function in Salesforce APEX, instead of Ruby.
Here is a comparison of code I just wrote to take a data-set of orders and to find the date associated with the first and last item in this list.
APEX Code:
```java global class LicenseCustomerOrderDateSorter implements Comparable { public License_Customer_Order__c order;
// Constructor
public LicenseCustomerOrderDateSorter(License_Customer_Order__c lco) {
order = lco;
}
// Compare opportunities based on the opportunity amount.
global Integer compareTo(Object compareTo) {
LicenseCustomerOrderDateSorter compareToOrder = (LicenseCustomerOrderDateSorter)compareTo;
// The return value of 0 indicates that both elements are equal.
Integer returnValue = 0;
if (order.Submitted_Date__c > compareToOrder.order.Submitted_Date__c) {
// Set return value to a positive value.
returnValue = 1;
} else if (order.Submitted_Date__c < compareToOrder.order.Submitted_Date__c) {
// Set return value to a negative value.
returnValue = -1;
} else if ((order.Submitted_Date__c == null) && (compareToOrder.order.Submitted_Date__c != null)){
// nulls-first implementation
returnValue = -1;
} else if ((order.Submitted_Date__c != null) && (compareToOrder.order.Submitted_Date__c == null)){
// nulls-first implementation
returnValue = 1;
}
return returnValue;
} } // Create a new custom sortable list wrapper LicenseCustomerOrderDateSorter[] orderList = new List<LicenseCustomerOrderDateSorter>(); for (License_Customer_Order__c lco : newLicenseCustomerOrders) {
orderList.add(new LicenseCustomerOrderDateSorter(lco)); } // Sort the list orderList.sort(); // Find the first and last date from the list DateTime firstDateTime = orderList[0].order.Submitted_Date__c; Integer lastElement = orderList.size() - 1; DateTime lastDateTime = orderList[lastElement].order.Submitted_Date__c; // Convert these to a date and time Date firstDate = Date.newInstance(firstDateTime.year(), firstDateTime.month(), firstDateTime.day()); Date lastDate = Date.newInstance(lastDateTime.year(), lastDateTime.month(), lastDateTime.day()); ```
Versus Ruby:
ruby
orderList.sort_by(&:Submitted_Date__c)
firstDate = orderList.first.Submitted_Date__c.to_date
lastDate = orderList.last.Submitted_Date__c.to_date
I spent about 2.5 hours writing the APEX code. And significantly less time writing the Ruby.
The Benefit of Ruby?
I estimate I would have to hire 5 times as many developers to develop custom software in APEX than creating the same function in Ruby.
Cost per development hour may be slightly higher for a Ruby Developer, but productivity will prove out to make this cost per hour exponentially less costly.
Addendum
One of our Salesforce friends, Henry who runs the Salesforce Consulting firm, Trausteknik, was talking to me about the benefits of Ruby and I showed him a draft of this blog post, he came back with a simpler approach to doing the list sort:
java
Map<Date, License_Customer_Order__c> orderMap = new Map<Date, License_Customer_Order__c>();
for(License_Customer_Order__c o : newLicenseCustomerOrders) {
orderMap.put(o.EffectiveDate, o);
}
List<Date> orderedDateList = new List<Date>(orderMap.keySet());
orderedDateList.sort();
//get first date
System.Debug(orderMap.get(orderedDate[0]).Description);
//get last date
System.Debug(orderMap.get(orderedDate[orderedDate.size() -1]).Description);
Which is definitely a lot less lines of code and probably about as fast… but it’s still not as nice to read :)