Code Tips #11: Ruby – Provide ways to iterate over collections

Sometimes we have classes that represent collections, for example a class Group can represent a collection of members

class Group
  def initialize(members)
    @members = members.dup
  end
end

When we want to iterate over the collection’s members we have to expose them through attr_reader

class Group
  attr_reader :members

  def initialize(members)
    @members = members.dup
  end
end

group1 = Group.new(["Nick", "Ana", "Petros"])

group1.members.each { |x| p |x| }

The problem with this approach is that the consumers of our collection have to know that we named our variable “members” and use it to iterate. If we ever rename this variable, the consumers of our collection have to rename their call as well. Moreover, we can’t control the order of the enumeration. What can we do to fix that? Continue reading Code Tips #11: Ruby – Provide ways to iterate over collections

Code Tips #10: Ruby – Compare objects

In a previous post I wrote about how to compare objects in Javascript. In Ruby we can do the same using the Comparable module. We include the comparable module in our class and we define a pseudooperator-method < =>. Let’s say we hava again a Car class that looks like this:

class Car
  attr :speed

  def initialize(speed)
    @speed = speed
  end
end

And now let’s make their instances comparable by Continue reading Code Tips #10: Ruby – Compare objects

Code Tips #9: Javascript – Compare objects

Many times we are in situations where we want to compare instances of a class, aka objects. Let’s see it with an example

class Car {
  constructor(speed){
    this.speed = speed
  }
}


const car1 = new Car(100)
const car2 = new Car(120)
const car3 = new Car(90)

console.log(car2.speed > car1.speed) // true

const sorted = [car1, car2, car3].sort((a,b) => {
  return a.speed - b.speed;
});

console.log(sorted) // [ Car { speed: 90 }, Car { speed: 100 }, Car { speed: 120 } ]

This works perfectly fine but we can do better Continue reading Code Tips #9: Javascript – Compare objects

Code Tips #8: Null Object Pattern

Many times functions accept object references that can be null, and we tend to add if statements to treat the special case where null is passed to a function, and either provide a default response or do nothing. In the following example our calculateSpeed function expects an object that has a getSpeed function. In Javascript we will have to do something like:

class Car {
  getSpeed(){
    return 100;
  }
}


const calculateSpeed = function(vehicle){
  if(vehicle && typeof vehicle.getSpeed === 'function'){
    return vehicle.getSpeed();
  } else {
    return 50;
  }
}

const car1 = new Car();

console.log(calculateSpeed(car1)); // 100
console.log(calculateSpeed()); // 50

But there is a better way to achieve that. Using the Null Object Pattern we can Continue reading Code Tips #8: Null Object Pattern

Code tips #7: Ruby – Keeping state across class instances and the problem with class variables

Class variables is a typical way to share state across instances of a class. Let’s say we have a Playlist class and we want to count how many instances of this class we have. We can write the following:

class Playlist
  @@number_of_playlists = 0

  def initialize
    @@number_of_playlists += 1
  end

  def play
    p "Playing..."
  end


  def get_number_of_playlists
    @@number_of_playlists
  end
end

The problem comes when Continue reading Code tips #7: Ruby – Keeping state across class instances and the problem with class variables

Code tips #6: Ruby – The clear way to declare static methods in a Class

In Ruby to define a static method in a Class, you can write the following:

class Song
  def Song.start
    p "Music start...!"
  end

  def Song.stop
    p "Music stop!"
  end
end

This works fine but in every function definition, you have to retype the name of the class, meaning that in case you decide to rename the Class you have to change all of these method names. A better solution would be Continue reading Code tips #6: Ruby – The clear way to declare static methods in a Class

Code tips #5: React – How to avoid extra control property

In React many times we have components that have some slight variations and we want to control how these components will be rendered. For example, we have a mobile and a desktop version of a component. Usually React developers tend to add an extra property in the component based on which they control the version of the component that will be rendered, either through if or switch statements.

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ProductCardSmall from './ProductCardLarge';
import ProductCardMedium from './ProductCardMedium';
import ProductCardLarge from './IPBadgeLarge';

export default class ProductCard extends Component {
  static propTypes = {
    cardType: PropTypes.string,
  };

  render() {
    const { cardType } = this.props;

    switch (cardType) {
      default:
      case 'small':
        return <ProductCardSmall {...this.props} />;
      case 'medium':
        return <ProductCardMedium {...this.props} />;
      case 'large':
        return <ProductCardLarge {...this.props} />;
    }
  }
}

And then use the component like:

<ProductCard cardType="medium" />

But there is a way to simplify the code by Continue reading Code tips #5: React – How to avoid extra control property

Code Tips #4: Let subclasses provide defaults

Inheritance is a powerful mechanism which allows us to share code and avoid duplication, but as Marvel’s comics teach us “With great power comes great responsibility”. Imagine a scenario where you have a superclass and some subclasses, the superclass provides some default values for the instances in case the parameter value is not passed.

class Vehicle{
  constructor(args = {}){
    this.speed = args.speed === undefined ? 100 : args.speed;
    this.color = args.color === undefined ? 'red' : args.color;
  }
}

The problem with this design is that Continue reading Code Tips #4: Let subclasses provide defaults

Code Tips #3: Remove argument-order dependency and provide defaults

Argument order in function signature is a common source of bugs and frustration. Imagine you have the following Vehicle class, its constructor accepts values to instantiate an object. Passing the values in the wrong order can easily lead to bugs that are not so easy to catch.

class Vehicle {
  constructor(speed, weight, power, color, brand){
    this.speed = speed;
    this.weight = weight;
    this.power = power;
    this.color = color;
    this.brand = brand;
  }
}

Continue reading Code Tips #3: Remove argument-order dependency and provide defaults

Code Tip #2: Isolate References to external classes

Imagine we have the following Vehicle class that has a dependency on the speed property of an Engine class.

class Engine {
  constructor(speed){
    this.speed = speed * 1.2;
  }
}

The Engine class accept a speed value and uses a factor to define the final speed. Its internals is not so important. Continue reading Code Tip #2: Isolate References to external classes