juan_gandhi: (Default)
Не о каких-нибудь там особо хитрых; в принципе, чуть ли не двоичных значений хватает, чтобы продемонстрировать.

Начнём, конечно, с Джавы. В которой сплошь и рядом, у "плохих программистов" встречается такое:
  if (message inscanceof CancellationMessage) { application.cancelnahren(); }
  else if (message instanceof EncouragementMessage) { galera.trabalha(); }
// etc


и хорошим программистам это не нравится, и они говорят "делегейшен давай", или "смартенумы давай!"

Делегейшен, это когда каждый параметр слишком широкого диапазона типов должен вдруг знать, что вот этот вот практически незнакомый тип однажды возьмёт да и обратится к ним, и надо для этого иметь особую форму (сиречь, сигнатуру), чтоб не подвести свой класс, а сделать, что положено (а там хоть не рассветай).

Ну или енум использовать - но енум контента не имеет, это константа... тогда люди ещё как поступают: в класс вставляют этот самый енум, "тип инстанса нашего класса".
  class Message {
    enum type {
      CANCEL,
      ENCOURAGE,
      DGAF} myType;
    ....
  }
...
  switch(message.type()) {
    case CANCEL: ...
    case ENCOURAGE: ...
    case DGAF: ...
  }


и это кошернее, чем было бы писать
  class mc = message.getClass();
  if (mc.equals(CancelMessage.class)) { ... }
  else if (....


В Скале же, на самом деле, не особо стесняются расписывать по классам, но на то есть другая причина: unapply, а ещё лучше сказать, линза (обратная сторона); с помощью её можно устраивать сравнение по образцу и, в зависимости от типа, выполнять какие-то действия с параметрами конструктора.
  message match {
    case CancelMessage(timeout: TimeInSeconds) => app.cancelato(timeout)
    case EncourageMessage(text: String) => galera.listen(text); galera.trabalha
    ...
  }


Фактически эта конструкция в некотором смысле помещает исполяемый, специфический для класса параметра, код немножко в контекст этого класса (видны только параметры конструктора).

В Скале есть немножко тенденция некоторые классы объявить более равными, например Option[T], Either[Left,Right] - для них как бы некошерно употреблять кейсы, а надо использовать функциональную функцию map. В принципе, скальные библиотеки любят возвращать Option[T], и тут-то бы и применять map, да штука в том, что в случае None ничего ни к чему применяться не будет. Так что приходится расписывать кейс. И со списками, что характерно, кейс приходится писать: как правило, разбивая ситуацию на два случая - пустой список или голова с хвостом, неважно, пустым или нет.

Так же и на Хаскеле - или мы матчим список, или Maybe, или data type.

И вот это вот "перечисление случаев" меня как-то смущает; нельзя ли для этого дела пристроить что-то вроде map? Но блин, это ж надо передавать, вообще говоря, по специальному исполнителю на каждый отдельный жизненный случай. Как в Джаве любят писать - лисинеры, listeners - они будут теперь здоровкаться на каждый чих.

Это практически cps, continuation passing style. Как в Джаваскрипте, если вы ещё помните, что такое xhr, а не вызываете что-нибудь там вроде JQuery.doAjaxForMeHurry(), то у вас как правило два-три таких слушателя: - пока читает, - когда закончили, - если ошибка. А могли бы написать (если б могли)

  reset {
    switch {
      case STILL_READING: ...; break
      case GOT_RESULT: ...; return
      case ERROR: ...; return
    }
    shift(k) {
      do {
        var resp = XHR.doPost(myStuff)
        k(resp)
      }
    }
  }


Это было бы почти идеальное решение, да?

Не знаю, не знаю.
juan_gandhi: (Default)
    public final static Pattern CRLF = Pattern.compile("\n\r|\r\n|\n");
    
    /**
     * Iterates over the lines of input.
     * 
     * Usage example:
     *    for (String s : iterate(new FileReader("system.properties")) {
     *       ...
     *    }
     *    
     * @param in
     * @return an iterable
     */
    public static Iterable iterate(final Readable in) {
        return iterate(in, CRLF);
    }
    
    /**
     * Iterates over the lines of input.
     * 
     * Usage example:
     *    for (String s : iterate(new FileReader("system.properties", "\n")) {
     *       ...
     *    }
     * 
     * @param in
     * @param delimiter
     * @return
     */
    public static Iterable iterate(final Readable in, String delimiter) {
        return iterate(in, Pattern.compile(delimiter));
    }
    
    /**
     * Iterates over the lines of input.
     * 
     * Usage example:
     *    for (String s : iterate(new FileReader("system.properties", Readables.CRLF)) {
     *       ...
     *    }
     * 
     * @param in
     * @param delimiter
     * @return
     */
    public static Iterable iterate(final Readable in, final Pattern delimiter) {
        return new Iterable() {

            @Override
            public Iterator iterator() {
                return new Scanner(in).useDelimiter(delimiter);
            }};
    }
решает вопрос


    /**
     * Iterates over a LineNumberReader
     * Usage:
     *   LineNumberReader r = new LineNumberReader(new InputStreamReader(new FileInputStream("system.properties")));
     *   for (String line : r) {
     *       ...
     *   }
     * @param in the source
     * @return an iterable that scans over the lines of the source
     * @throws IOException when it cannot read the first line
     * @throws RuntimeException when it cannot read further down the stream
     */

    public static Iterable<String> iterate(final LineNumberReader in) throws IOException {
        final String first = in.readLine();
        return new Iterable<String>() {

            @Override
            public Iterator iterator() {
                return new Iterator() {
                    String current = first;

                    @Override
                    public boolean hasNext() {
                        return current != null;
                    }

                    @Override
                    public String next() {
                        if (!hasNext()) {
                            throw new NoSuchElementException();
                        }
                        try {
                            return current;
                        } finally {
                            try {
                                current = in.readLine();
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }

                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                    
                };
            }};
    }



juan_gandhi: (Default)
    /**
     * Iterates over a LineNumberReader
     * Usage:
     *   LineNumberReader r = new LineNumberReader(new InputStreamReader(new FileInputStream("system.properties")));
     *   for (String line : r) {
     *       ...
     *   }
     * @param in the source
     * @return an iterable that scans over the lines of the source
     * @throws IOException when it cannot read the first line
     * @throws RuntimeException when it cannot read further down the stream
     */

    public static Iterable<String> iterate(final LineNumberReader in) throws IOException {
        final String first = in.readLine();
        return new Iterable<String>() {

            @Override
            public Iterator iterator() {
                return new Iterator() {
                    String current = first;

                    @Override
                    public boolean hasNext() {
                        return current != null;
                    }

                    @Override
                    public String next() {
                        if (!hasNext()) {
                            throw new NoSuchElementException();
                        }
                        try {
                            return current;
                        } finally {
                            try {
                                current = in.readLine();
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }

                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                    
                };
            }};
    }

juan_gandhi: (Default)
Spent like an hour trying to figure out how to serialize to json the object I build from json (to pass around the network); then it occurred to me it's immutable. Why not keep the source, eh. Like class files, they'd be happier if they just had the source code accompanying them naturally somewhere, eh.

So there. I just store the object's own source. Neat, eh.

so...

Jul. 13th, 2011 05:15 pm
juan_gandhi: (Default)
    @Test
    public void testPutAll() throws Exception {
        File folder = new File(ROOT, "Shakespeare");
        folder.mkdirs();
        Folder f = new Folder(folder);
        Map<String, ByteArray> m = Maps.newHashMap();
        m.put("sonnet1.1", new ByteArray("From fairest creatures we desire increase"));
        m.put("sonnet1.2", new ByteArray("That thereby beauty's rose might never die"));
        m.put("sonnet1.3", new ByteArray("But as the riper should by time decease"));
        m.put("sonnet1.4", new ByteArray("His tender heirs bear his memory"));
        f.putAll(m);
        assertEquals(m, f);
    }
juan_gandhi: (Default)
Just wrote a couple of methods in my main mock class.

public void failingOn(String regex) {
  this.failureCondition = regex;
}

public void maybeFail(Object...objects) throws HBaseException {
  if (failureCondition != null) {
            String s = Arrays.asList(objects).toString();
    if (s.matches(failureCondition)) {
      throw new HBaseException("Congratulations, you hit the jackpot today: " + s);
    }
  }
}



and most of the methods look like this:

@Override
public void bulkDelete(String tableName, Collection rowKeys, String columnFamily) throws HBaseException {
  maybeFail("bulkDelete", tableName, rowKeys, columnFamily);
  table(tableName).family(columnFamily).delete(rowKeys);
}


Now in the test I write stuff like this:
@Test    
public void testPut_replicating_withErrors() throws Exception {
  MockHBaseOperations cluster2 = new MockHBaseOperations();
  cluster2.failingOn("\\[sendToCluster, BadTable,.*");
  ...
}


... do you need explanations on how it works?

What I personally enjoy here is the leisure JavaScript coding style, where you just join the arguments, not giving a fuck about their types.
juan_gandhi: (Default)
/**
   * @return the number of families in familyMap
   */
  public int numFamilies() {
    if(hasFamilies()) {
      return this.familyMap.size();
    }
    return 0;
  }

  /**
   * @return true if familyMap is non empty, false otherwise
   */
  public boolean hasFamilies() {
    return !this.familyMap.isEmpty();
  }
juan_gandhi: (Default)
What do you think?

  public class BaseClass<T extends BaseClass<?>> {
    //...
    protected BaseClass(/*parameters and arguments*/) {
      //...
    }

    public T self() {
      return (T) this;
    }
  }


The right solution, right?
juan_gandhi: (Default)
public class TimeStats extends Stats {
	private static final double MS = 0.000001;
	private long startedNano;

	public void start() {
		startedNano = System.nanoTime();
	}
	
	public void finish() {
		add(System.nanoTime() - startedNano);
	}

	public String millis(double nano) {
		return MS * nano + "ms";
	}
	
	public String toString() {
		return "min: " + millis(min) + ", max:" + millis(max) + ", avg:" + millis(average());
	}
}
juan_gandhi: (Default)
I'm pretty much tired of using so-called "DAO objects", automatically hibernate-generated classes that are dumb and simple; they are being used everywhere throughout the code; I was always willing to fill them with functionality, but, thank god, there was no chance.

Now I think this. Thanks to [livejournal.com profile] mikkim08 ideas for Scala. They should be all wrapped in decorators; and decorators should be returned from DAOs or factories. Performance-wise, it is just one level of indirection, and one more reference per instance. Conceptually, it is an implicit mapping.

E.g. I get "CountryData" from db; it is dumb and know nothing about life, just data. Wrap it in a subclass, and kaboom, an intelligent guy who can tell you this and that... and yes, immutable, since all "setters" are blocked by police.

So there.
juan_gandhi: (Default)
How come Java's Byte is not a subclass of Integer? Barbara told so? Barbara would be happy to agree that you can pass Byte as a parameter in any (contravariant) position where an Integer is accepted. This is true for byte and int, so?

I must be missing something obvious and important... am I?

ant

Feb. 7th, 2011 09:30 pm
juan_gandhi: (Default)
I have a confession to make. I used ant since about y2k. Hated it with all my soul. You can't change an attribute once set. Etc. Unreadable. Etc.

Now I enjoy it, and respect it a lot. It is immutable. That's so cool. It is so functional style. I just was not getting it.

So there. Took me a lot of time, eh.
juan_gandhi: (Default)
got an ec2 instance; tried apt-get, kaboom, it's not there. So I guess I have to download rpms and install. Starting with Java - seems like sracle does not allow you to do curl (wants some kind of cookie, whatever)

So I had cached the stuff on my site (should I actually use some kind of box instead?)

http://myjavatools.com/archive/java/jdk-6u23-linux-i586-rpm.bin
http://myjavatools.com/archive/ec2/ec2-ami-tools.noarch.rpm
http://myjavatools.com/archive/texlive-latex-2007-46.fc10.i386.rpm

UPDATE: discovered yum (is it fedora's apt-get?)

Profile

juan_gandhi: (Default)
Juan-Carlos Gandhi

September 2025

S M T W T F S
 1 2345 6
78 9 10 111213
14151617181920
21222324252627
282930    

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 12th, 2025 03:10 pm
Powered by Dreamwidth Studios