CopyAndPaste

random programming notes

Default Encoding

To change ruby encoding, run ruby with -E [coding].

Example:

1
2
#!/bin/ruby -E UTF-8
ruby code here

Java Object Creation

Work in progress

Notes from reading “Effective Java”

Static factory method

  • advantages
    • with names
    • not required to create new object when invoked
    • can return object of any subtype of its return type
  • disadvantages
    • classes without public or protected constructors cannot be subclassed
1
2
3
4
5
6
7
8
9
public class Foo {
  private Foo() {}
  public static Foo getInstance() {
      //...
  }
  public static Foo valueOf(bool value) {
      //... 
  }
}

Builder

Used when there are many constructor parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public class Foo {
  private final int required1;
  private final int required2;
  private final int optional1;
  private final int optional2;
  
  public static class Builder {
      // required 
      private final int required1;
      private final int required2;
      // optional 
      private final int optional1;
      private final int optional2;
      
      public Builder(int required1, int required2) {
          this.required1 = required1;
          this.required2 = required2;
      }
      
      public Builder required1(int val) {
          required1 = val;
          return this;
      }
      public Builder required2(int val) {
          required2 = val;
          return this;
      }
      public Builder optional1(int val) {
          optiona1 = val;
          return this;
      }
      public Builder optional2(int val) {
          optiona2 = val;
          return this;
      }
      
      public Foo build() {
          return new Foo(this);
      }
  }
  
  private Foo(Builder builder) {
      required1 = builder.required1
      required2 = builder.required2
      optional1 = builder.optional1
      optional2 = builder.optional2
  }
}

// usage example 
Foo fooInstance = new Foo.Builder(10, 10).optional1(100).optional2(200).build();

// build should throw IllegalStateException if parameters violate rules 

// method that uses Builder 
// assume Builder is defined as: 

public interface Builder<T> {
  public T build();
}

Tree nodeMethod(Builder<? extends Node> nodeBuilder) {
  //...
}

advantages:

  • no long, unnamed list of parameters
  • can fill up optional values
  • disadvantages:

  • speed

Suppress Stdout and Stderr When Running RSpec

Sometimes code prints to stdout, stderr. Corresponding RSpec examples print the same output, which could be messy. To suppress the output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def silence
  # Store the original stderr and stdout in order to restore them later
  @original_stderr = $stderr
  @original_stdout = $stdout

  # Redirect stderr and stdout
  $stderr = $stdout = StringIO.new

  yield

  $stderr = @original_stderr
  $stdout = @original_stdout
  @original_stderr = nil
  @original_stdout = nil
end

it "suppresses output" do
  silence do
      # whatever code to test 
  end
end

Mocking Backtick in RSpec

`cmd` is a method in Kernel.

However, simply mocking the Kernel object does not work. This is because Kernel is a module included by class Object, its methods are available in every Ruby object.

Instead of doing this:

1
2
3
Kernel.expects(:`).with(
  'unzip -d /tmp test.zip'
)

We should be doing this:

1
2
3
instance_of_current_object.expects(:`).with(
  'unzip -d /tmp test.zip'
)

User-defined Metadata in Rspec

Rspec describe, context and it supports metadata in the form of a hash. Syntax as follow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
RSpec.describe "some description", :foo => 1, :bar do

  context "when some condition", :value => true do
  
      it "does something", :hihi, :day => 10 do |example|
          expect(exapmle.metadata[:foo]).to eq(1)
          expect(example.metadata[:value]).to be true
          expect(example.metadata[:hihi]).to be true
          expect(example.metadata[:day]).to eq(10)
      end
  
  end
  
end

There are 2 ways that I use metadata in RSpec.

To include shared_examples / shared_context

RSpec includes shared_context and shared_examples with same metadata

1
2
3
4
5
RSpec.shared_context "shared stuff", :a => :b do
  def shared_method
      pp "hello"
  end
end
1
2
Rspec.describe "use shared stuff", :a => :b do
end

is equivalent to

1
2
3
Rspec.describe "use shared stuff" do
  include_context "shared_stuff"
end

Use metadata as variables

1
2
3
4
5
6
7
8
9
10
11
RSpec.describe "use metadata as var", :num_elements => 7 do

  let(:elements) do |example|
      (1..example.metadata[:num_elements]).map { |n| "element#{n}" }
  end
  
  it "prints elements" do
      pp elements
  end

end