100
Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com

Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

Ruby On Railsweb development that doesn’t hurt

Boris Nadionastrails.com

Page 2: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

web development that doesn’t hurt

Page 3: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

doesn’t hurt businesses

Page 4: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

doesn’t hurt developers

Page 5: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

software

Page 6: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

software development background

Page 7: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

organic

Page 8: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

you always find things you want to change

Page 9: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

great ideas

Page 10: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

adaptive developmentagile, scrum, xp, etc.

Page 11: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

small iterations

Page 12: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

continuous delivery

Page 13: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

simplicity

Page 14: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

tools?

Page 15: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

what programmers need?

Page 16: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

inspiration

Page 17: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

challenge

Page 18: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

compensation

Page 19: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

do programmerslike programming?

Page 20: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

programmers don’t like programming

we would be programming assembler still

Page 21: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

solving complex problems in beautiful ways

Page 22: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

programming languageis a tool

Page 23: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

happy

Page 24: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

easy to learn

Page 25: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

make problems easier to solve

Page 26: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

increase chance of success

Page 27: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

that’s why Ruby on Rails programmers are happy

Page 28: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

Ruby on Rails born to be agile

Page 29: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

extremely flexible

Page 30: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

rapid development

Page 31: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

focus on productivity

Page 32: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

maintainable code

Page 33: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

free

Page 34: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

what is Ruby on Rails?

Page 35: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

Ruby is a language

Page 36: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

Yakihiro Matsumoto “matz”

Page 37: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

1993

Page 38: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

1995

Page 39: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

free to use, copy, modify, and distribute

Page 40: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

POLSprinciple of least surprise

Page 41: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

easy to read a code

Page 42: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

guess how it works -guess correctly

Page 43: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

humans should easily understand the code, not

computers

Page 44: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

are you a human?

Page 45: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

3.times { say "Hello" }

return if presentation.looks?(:boring)

["espresso", "cappuccino", "latte"].each do |drink| print drink.capitalizeend

Page 46: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

almost pure English

Page 47: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

less code

Page 48: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

less code - less bugshigh maintainability

Page 49: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Date; public class TimeServer { private static class TellTime extends Thread { private Socket soc; public TellTime(Socket soc) { super(); this.soc = soc; } public void run() { try { this.soc.getOutputStream().write( new Date().thisoString().getBytes()); } catch (Exception e) { } finally { try { this.soc.close(); } catch (IOException e1) { } } } } public static void main(String args[]) throws Exception { ServerSocket server = new ServerSocket(12345); while (true) { new TellTime(server.accept()).start(); } } }

require "socket" server = TCPServer.new(12345) while (session = server.accept) Thread.new(session) do |my_session| my_session.puts Time.new my_session.close end end

Page 50: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

high signal to noise ratio

Page 51: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Date; public class TimeServer { private static class TellTime extends Thread { private Socket soc; public TellTime(Socket soc) { super(); this.soc = soc; } public void run() { try { this.soc.getOutputStream().write( new Date().thisoString().getBytes()); } catch (Exception e) { } finally { try { this.soc.close(); } catch (IOException e1) { } } } } public static void main(String args[]) throws Exception { ServerSocket server = new ServerSocket(12345); while (true) { new TellTime(server.accept()).start(); } } }

require "socket" server = TCPServer.new(12345) while (session = server.accept) Thread.new(session) do |my_session| my_session.puts Time.new my_session.close end end

Page 52: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

less code - less efforthigh productivity

Page 53: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

credit: http://www.flickr.com/photos/slworking/

Page 54: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

Rails is a framework

Page 55: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

David Heinemeier Hansson

Page 56: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

2003

Page 57: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

MIT license

Page 58: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

opinionated

Page 59: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

convention over configuration

Page 60: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

no XML configuration files

Page 61: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

default places and names for files, tables, etc

Page 62: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

you can override everything

Page 63: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

c = Company.firstc.name

app/models/company.rbclass Company < ActiveRecord::Baseend

select * from companies limit 1;

Page 64: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

MVC

Page 65: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

Model - View - Controller

Page 66: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

concerns separation

Page 67: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

MVC

Page 68: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

business logic in modelsfetch the data

Page 69: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

credit: http://www.flickr.com/photos/simonpais/

Page 70: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

adaptersMySQL, SQLite, PostgeSQL, MS SQL, Oracle, DB2,

MongoDB, Cassandra, ...

Page 71: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

class Post < ActiveRecord::Base belongs_to :user has_many :comments

validates :subject, :presence => true validates :body, :presence => true

after_create :notify_subscibersend

Page 72: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

display logic in viewsrender the data

Page 73: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

templatesERB, HAML, Liquid, Amrita, Markaby, ...

Page 74: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

<html> <body> User <%= @user.name %>: <ul> <li>Age: <%= @user.age %></li> <li>Interests: <%= @user.interests.join(', ') %></li> <li>Occupation: <%= @user.occupation %></li> </ul></body></html>

Page 75: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

%html  %body    User = @user.name     %ul      %li Age = @user.age %li Interests = @user.interests.join(', ') %li Occupation = @user.occupation

Page 76: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

user logic in controllershandle requests

Page 77: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

RESTrepresentational state transfer

Page 78: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

GET /books {:action=>"index", :controller=>"books"}POST /books {:action=>"create", :controller=>"books"}GET /books/new {:action=>"new", :controller=>"books"}GET /books/:id/edit {:action=>"edit", :controller=>"books"}GET /books/:id {:action=>"show", :controller=>"books"}PUT /books/:id {:action=>"update", :controller=>"books"}DELETE /books/:id {:action=>"destroy", :controller=>"books"}

Page 79: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

class BooksController < ActionController::Base

def create @book = Book.new(params[:book]) if @book.save flash[:notice] = "Book created" # The entry was saved correctly, redirect to index redirect_to books_path else flash.now[:notice] = "Fix errors and try again" render :action => :new end end

...

end

Page 80: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

webserver

controller modelview

db

request

dispatch/routing

query

usesrenders

displays

simplified flow

Page 81: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

testing

Page 82: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

testing frameworkstest::unit, rspec, micronaut, cucumber, shoulda, ...

Page 85: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

TAFTtest all the f$cking time

Page 86: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

ruby gems and rails plugins

Page 87: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

bottom line

Page 88: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

optimized for programmer happiness and sustainable

productivity

Page 89: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

Ruby on Railsagile: perfect for web startups

Page 90: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

what do you do next?

Page 92: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

learn Ruby on Rails

Page 93: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

learn the best practices

Page 94: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

apply it to yournext killer project

Page 95: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

it won’t hurt

Page 96: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

web development that doesn’t hurt

Page 97: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

Q&A

Page 98: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

does it scale?

Page 99: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

yes

Page 100: Ruby On Railsassets.astrails.com/presentations/2011-02-17-thejunction/doesnt-hur… · Ruby On Rails web development that doesn’t hurt Boris Nadion astrails.com. web development

Ruby On Railsweb development that doesn’t hurt

Boris Nadionastrails.com

Thank you!Q&A