Hatena::ブログ(Diary)

菊やんの雑記帳

2009-03-13 dddddmap

[] dddddmapとか作るとよくね? 23:07  dddddmapとか作るとよくね? - 菊やんの雑記帳 を含むブックマーク

http://d.hatena.ne.jp/ku-ma-me/20090312 を見て思ったんだけど、

x.ddmap.f ==> x.dmap.f.dmap
x.dddmap.f ==> x.dmap.f.ddmap
x.ddddmap.f ==> x.dmap.f.dddmap

とか作れば

x.map{|y|y*3/5+2}

とかが

x.dddmap*3/5+2

ってできて便利じゃね。

適当にこぴってきて実装した(Ruby1.8だけど)

module Enumerable
  def dmap(n=1)
    DelegateMap.new(n, self)
  end
  2.upto(10) {|n|
    eval "def #{'d'*n}map; dmap(#{n}); end"
  }
end

class DelegateMap
  def initialize(n, enum)
    @n = n
    @enum = enum
  end
  def method_missing(mhd, *args, &blk)
    r = @enum.map {|elem| elem.__send__(mhd, *args, &blk) }
    @n > 1 ? r.dmap(@n-1) : r
  end
end

これを使うと

[[[[[1]]]]].dddddmap.ddddmap.dddmap.ddmap.dmap*5
=> [[[[[5]]]]]

みたいに多重配列の中に簡単に入るようになる(ぉ

[[[[[1]]]]].ddddddmap.dddddmap.ddddmap.dddmap.ddmap*5+3
=> [[[[[8]]]]]

こんなのも簡単にできるし、必要な文字数もO(2^n)からO(n^2)に大幅ダウンだ。

2007-06-14 Rails+SQLite3

[] ActiveRecordのバグ発見した 22:53  ActiveRecordのバグ発見した - 菊やんの雑記帳 を含むブックマーク

http://dev.rubyonrails.org/ticket/8642

RailsSQLite 使ってて BusyException で死んだまま復活しなければこれ。

ほかのDBでも起こりうると思うけど。

2007-03-02 Railsのバリデーション

[] 09:11 Railsのバリデーション - 菊やんの雑記帳 を含むブックマーク

Ruby on Rails での入力の検証方法について書く。世の中にあまねくRailsのページによると、以下のような感じで入力を検証するのがRails流らしい。

# モデルクラス。
class Hoge < ActiveRecord::Base
  validates_length_of :name, :maximum => 30
end

# コントローラ
class HogeController < ApplicationController
  # アクション。新しいHogeを作成する。
  def create
    @hoge = Hoge.new(params[:hoge])
    if @hoge.save
      redirect_to :action => :list
    else
      render :action => :new
    end
  end
end

ユーザがフォームに適当に入力してボタンを押すと、コントローラのcreateメソッドが呼び出される。ユーザが入力した内容はそのままモデルの作成パラメタとしてコンストラクタに渡される。そして、モデルを保存しようとすると、モデルの検証メソッドが呼び出され、失敗した場合は保存しない。

あえていおう!カスであると!

この方法は二種類の異なった検証をごちゃ混ぜにしてモデルクラスに押し付けている。すなわち、ユーザの入力内容の検証とモデルオブジェクトの整合性の検証である。これらの一番の違いは検証失敗時の責任の所在で、入力の検証の失敗はユーザの責任でありエラーメッセージを表示し再入力を促さなければならない。整合性の検証の失敗の責任はプログラマにありエラーログに記録して内部エラーを報告すべきだろう。

というわけで、コントローラとモデルでは別の検証を書くべきであるが、一般に入力の検証のほうが厳しいわけで、モデルの検証を拡張して入力の検証を行える仕組みを持つのが好ましい。

というか健全なフレームワークはそうあるべきだ。

2006-11-07 記号ゴルフ

[] 05:05 記号ゴルフ - 菊やんの雑記帳 を含むブックマーク

なんか答えきぼんぬされたので、

StackError

load$0
{}[$*<<$*]

quine

_=';$><<["_=",_,_]*(""<<-~?&)';$><<["_=",_,_]*(""<<-~?&)

引用符が二種類あるからCより楽だね(たぶん。

と思ってたんだけど、改行ありなら

$><<[__=<<_,__,'_']
$><<[__=<<_,__,'_']
_

で書ける。0H41B。

と思ったら全部`_'でいいんじゃん。全然気づいてなかった。

簡単に歴史。最初はCの有名なquine

char*p="char*p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}

そのままRubyで書くと

_="_=%c%s%c;printf _,34,_,34";printf _,34,_,34

「%c%s%c」のとこが記号ゴルフ的に問題なので、安直に

_="_=!;_[/!/]=''<<34<<_<<34;$><<_";_[/!/]=''<<34<<_<<34;$><<_

ここがスタート地点で、がりがり削っていくと上のコードになる。

shinichiro_hshinichiro_h 2006/11/07 12:22 回答ありがとうございました。すごいなぁという感です。
flagitious 氏の考えていた quine は puts 2*2,2 の *2 のかわりに $. を使うというようなものでした。ですが本質とあまり関係ないところで 2B だけ kik さんのより短かったです。内容はおそらくご自身で気付かれるでしょうしとりあえず伏せておきますね。

2006-10-30 記号ゴルフ

[] 03:26 記号ゴルフ - 菊やんの雑記帳 を含むブックマーク

無限ループは

id:shinichiro_h:20061030#1162211956

はまあこんな感じでしょう。

いろいろ考えててふと思いついたのだが

「stack level too deep (SystemStackError)」

このエラーを発生させるコードを書くというお題は面白いかも。

記号ゴルフ・通常ゴルフどちらでも問題にできそう。


とりあえず、どっちかは秘密だけど11Bになった。

とか思ってたら10Bになった。

とか思ってたら、メモリ食わずに3Hで無限ループできるじゃん。とりあえず3H28Bになった。

とか思ってたら、id:shinichiro_h 氏は6Bか…どうやったんだろう。

記号でも通常でも10Bだと信じていたのに…

quineの1Hはたぶん「p」なんでしょうが「p」なんてぶっちゃけ必要ないので、0H69Bを安直に作った。たぶんまだまだ縮む。

[] 00:32 記号ゴルフ - 菊やんの雑記帳 を含むブックマーク

というわけで、

  • StackError
    • 記号だと0H10Bが最小?
    • 全てだと6B (これは使っていい関数なのか?)
  • 無限ループ
    • 記号でメモリ食いはk.inaba氏の0H10B
    • 記号でメモリ食わずはk.inaba氏の3H?B
    • 私が考えてたメモリ食わずは、(" ".."_").all?{|_|_[/./]=$/} なループ変数を勝手に書き換えるものでしたが、最初から進まないのがあるのには気づかなかった…
  • quine
    • 結局0H56Bまで縮んだ。
    • mameは0H0Bが最小だといっている。

k.inabak.inaba 2006/11/01 00:54 0H0B...(笑)
(””..”_”).min の3H13Bが今のところ思いついた記号メモリ食わずです。

mamemame 2006/11/02 00:58 ruby を segv させる。0H5B