Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Making Sourcery write code for you

Making Sourcery write code for you

Marcilio Junior

August 20, 2019
Tweet

More Decks by Marcilio Junior

Other Decks in Programming

Transcript

  1. Marcílio Júnior iOS Developer @ Teamwork Teacher @ PUC Minas

    #iOSDev since 2011 #RemoteWorker since 2014
  2. Agenda 1. What is meta programming 2. What is Sourcery

    3. Stencil 4. Using Sourcery to write your API client
  3. Technique in which a computer program can be designed to

    read, generate, analyze or transform other programs, and even modify itself while running.
  4. What is meta-programming? • Some languages that have this feature:

    ◦ Ruby ◦ Python ◦ Rust ◦ Elixir ◦ Smalltalk
  5. Why use Sourcery? 1. Less repetitive code to write (DRY

    principles) 2. Allows create better code 3. Limits the risk of introducing human error when refactoring 4. Less code less bugs
  6. {% for enum in types.implementing.AutoCases|enum %} {{ enum.accessLevel }} extension

    {{ enum.name }} { static let count: Int = {{ enum.cases.count }} {% if not enum.hasAssociatedValues %} static let allCases: [{{ enum.name }}] = [ {% for case in enum.cases %} .{{ case.name }}{{ ',' if not forloop.last }}{% endfor %} ] {% endif %} } {% endfor %}
  7. protocol ApiClientProtocol { func fetchAll(completion: @escaping ((Result<[Todo], Error>) -> Void))

    } class ApiClient: ApiClientProtocol { func fetchAll(completion: @escaping ((Result<[Todo], Error>) -> Void)) { // ... build URL URLSession.shared.dataTask(with: url) { (data, _, error) in guard let data = data else { completion(.failure(error!)) return } let todos = try! JSONDecoder().decode([Todo].self, from: data) completion(.success(todos)) }.resume() } }
  8. class ApiClient: ApiClientProtocol { func fetchAll(completion: @escaping ((Result<[Todo], Error>) ->

    Void)) { // ... build URL URLSession.shared.dataTask(with: url) { (data, _, error) in guard let data = data else { completion(.failure(error!)) return } let todos = try! JSONDecoder().decode([Todo].self, from: data) completion(.success(todos)) }.resume() } }
  9. // sourcery: baseUrl = "https://base.url.com" // sourcery: path = "/todo"

    // sourcery: method = .get // sourcery: contentType = "application/json" // sourcery: token = "token" // sourcery: response = [Todo] func fetchAll(completion: @escaping ((Result<[Todo], Error>) -> Void)) protocol ApiClientProtocol { }
  10. Conclusion 1. Less repetitive code to write (DRY principles) 2.

    Allows create better code 3. Limits the risk of introducing human error when refactoring 4. Less code less bugs
  11. Conclusion 1. Less repetitive code to write (DRY principles) 2.

    Allows create better code 3. Limits the risk of introducing human error when refactoring 4. Less code less bugs
  12. Conclusion 1. Avoid copy/pasting 2. Allows create better code 3.

    Limits the risk of introducing human error when refactoring 4. Less code less bugs
  13. Conclusion 1. Avoid copy/pasting 2. Allows create better code 3.

    Limits the risk of introducing human error when refactoring 4. Less code less bugs
  14. Conclusion 1. Avoid copy/pasting 2. Efforts in the stencil template

    and where matters 3. Limits the risk of introducing human error when refactoring 4. Less code less bugs
  15. Conclusion 1. Avoid copy/pasting 2. Efforts in the stencil template

    and where matters 3. Limits the risk of introducing human error when refactoring 4. Less code less bugs
  16. Conclusion 1. Avoid copy/pasting 2. Efforts in the stencil template

    and where matters 3. Only one place to refactor 4. Less code less bugs
  17. Conclusion 1. Avoid copy/pasting 2. Efforts in the stencil template

    and where matters 3. Only one place to refactor 4. Less code less bugs
  18. Conclusion 1. Avoid copy/pasting 2. Efforts in the stencil template

    and where matters 3. Only one place to refactor 4. Less code less bugs