ページ

2004年5月25日火曜日

文字列比較のパフォーマンス

どうやら、一部で流行っているようなので...(^^;



String s1 と String s2 があった場合に、両者が同じかどうかを比較するには



  1. s1.Equals(s2)
  2. String.Equals(s1, s2)
  3. s1 == s2

という 3種類の方法があります。
で、「どれが一番速いのよ?」 という話題ですね。


以下は sscli のソースと .NET Framework 1.1 をちょっと覗き見た内容です。


まず、3 の s1 == s2 は単に 2の String.Equals(s1, s2) を呼び出すだけです。
注意:  VB.NET の s1 = s2 は Microsoft.VisualBasic.CompilerServices.StringType.StrCmp を呼び出すそうですが、C# では単に String.operator ==(s1, s2) を呼び出すだけです。ちなみに、operator== は op_Equality とも表記されます(というか、IL 的には op_Equality のほうが正式名だと思いますが)。


次に、2 の String.Equals(s1, s2) ですが、これは
 a. s1 と s2 が同じオブジェクトなら true を返す。
 b. s1 か s2 が null なら false を返す。
 c. どちらでもないときは 1 の s1.Equals(s2) を呼び出す。
となっています。


で、1 は internalcall といって .NET Framework の内部に実装された関数にマップされています。


というわけで、どれが一番速いかは明らかですね。3 は 2 を呼び、2 は 1 を呼ぶ、という実装なんですから、1 が一番速くて 3 が一番遅いということになります。


ただ、ちょっと注意があります。s1、s2 が同じオブジェクトだった場合、もしくは、どちかが null だった場合は 2 が一番速いという結果になることが多いんじゃないかと思います。
ここで、C# だと同じ文字列定数は自動的に同じオブジェクトになります。それは以下のようにすれば確認できます。


string s1 = "aaa";
string s2 = "aaa";
if ((object)s1 == (object)s2) {
    Console.WriteLine("同じオブジェクト");
}

同じ文字列だけど別のオブジェクトを生成したいときは StringBuilder を使ってやればいいようです。


StringBuilder sb1 = new StringBuilder("aaa");
string s1 = sb1.ToString();
StringBuilder sb2 = new StringBuilder("aaa");
string s2 = sb.ToString();
if ((object)s1 == (object)s2)
{
    Console.WriteLine("同じオブジェクト");
}

# 1つの StringBuilder から 2回 ToString() してやっても別々のオブジェクトに
# なるようではありますが。

やっぱり出てた。VS 2005 CTP May 2004

MSDN の Subscriber Downloads に以下のものがすでにあります。


Visual Studio 2005 Community Technology Preview May 2004 - 32 Bit (English)
Visual Studio 2005 Community Technology Preview May 2004 - 64 Bit (English)


# March じゃなくて May だよ。


ちなみに、32 Bit が 2.53GB の ISO イメージ、64 Bit が3.32GB の ISO イメージです。


64 Bit には当然 .NET Framework 2.0 の 64 Bit 版が入っていると想像してるんですが、こんなにサイズが違うのはなんでなんだろう?
求む、人柱(^^;

Visual Studio 2005 Team System なんてものが登場

こちらのページ。
http://msdn.microsoft.com/vstudio/teamsystem/


まだ読んでないんですが(^^
今まで Visual Studio は開発ツール(コードを書いてコンパイルしてデバッグする)ためのものっていう感じでしたが、Visual Studio 2005 からはだいぶイメージが変わるのかな?



  • for Architects

  • for Developers

  • for Project Managers

  • for Team Development

  • for Testers

のそれぞれが紹介されています。


おそらく TechEd で発表されたんでしょうね。詳細情報求む>現地の人(^^;

2004年5月21日金曜日

C# の Generics

今さらながら .NET Framework 2.0 で搭載される Generics のことです。
といっても解説じゃありません(^^;


基本的には以下のような感じですね。
(以下に書いているコードは VS2005 CTP March 2004 では動きました)



private static void TestGenerics()
{
    List<int> l = new List<int>();
    l.Add(0);
    l.Add(1);
    l.Add(2);
    l.Add(3);
 
    // 普通に Count でループ
    for (int i = 0; i < l.Count; ++i)
    {
        Console.WriteLine(l[i].ToString());
    }
 
    // もちろん foreach でもループできる
    foreach (int n in l)
    {
        Console.WriteLine(n.ToString());
    }
}


通常版では自動拡張する配列は ArrayList クラスでしたが、Generics 版は List クラスになってます(たぶん(^^; リファレンスに List が見つからないんですが)。といっても、Generic なだけで使い方は ArrayList とほとんど同じです。


ただ、ArrayList はほんとに単なる 「自動拡張する配列」 でしたが、List にはいろいろとメソッドが増えてます。たとえば、Find とか。で、おもしろいのは、この Find の引数って Inttelisense で 「Predicate match」 って出てくるんですよ。Predicate ってなにかと言うと、
  public sealed delegate bool Predicate(T obj);
という Generic な delegate なんですね。
ついでに言うと、Find の戻り値は Nullable だそうです。なるほど、たとえ T が値型だったとしても、見つからなかったときに null が返せるように Nullable になってるわけですね。


で、Find を使ったコードはというと以下のような感じ。



private static void TestGenerics()
{
    List<int> l = new List<int>();
    l.Add(0);
    l.Add(1);
    l.Add(2);
    l.Add(3);
 
    // 0 か 2 のものを探して表示
    Console.WriteLine(l.Find(IsZeroOrTwo).Value.ToString());
}
 
private static bool IsZeroOrTwo(int n)
{
    return n == 0 || n == 2;
}


ここでは、static なメソッドである IsZeroOrTwo を delegate のコールバックメソッドとして使ってます。この場合 0 と 2 の 2つが見つかりますが、Find は最初に見つかったほうだけを返すので 0 だけが表示されます。
あぁ、そうそう、検索した結果見つからなくて null が返ってきたときのチェックを省略しちゃってますが、もちろん、ほんとはすべきです。


どうでしょ?すごくイイ!と思いませんか?(私は激しく思います。色を変えたくなるくらい)
ただ、C++ の STL を知らないと Predicate の考え方がわかりにくいかもしれませんね。


もう 1つ。List.FindAll もあります。これは見つかったやつをみんな返すっていうメソッドです。なので、戻り値は List です。引数は Find と同じ。
それと ForEach っていうメソッドもあります。これの引数は 「Action action」 です。Action も、
  public sealed delegate void Action(T obj);
です。Predicate との違いは戻り値が void なところだけですね。


この FindAll と ForEach を使うと、



private static void TestGenerics()
{
    List<int> l = new List<int>();
    l.Add(0);
    l.Add(1);
    l.Add(2);
    l.Add(3);
 
    // 0 か 2 のものを探して表示
    l.FindAll(IsZeroOrTwo).ForEach(WriteLine);
}
 
private static bool IsZeroOrTwo(int n)
{
    return n == 0 || n == 2;
}
 
private static void WriteLine(int n)
{
    Console.WriteLine(n.ToString());
}


こんな感じに書けます。


さらに...
delegate は Anonymous Method として書けるはずです。ということは...



private static void TestGenerics()
{
    List<int> l = new List<int>();
    l.Add(0);
    l.Add(1);
    l.Add(2);
    l.Add(3);
 
    l.FindAll(delegate(int n)
    {
        return n == 1 || n == 3;
    }).ForEach(delegate(int n)
    {
        Console.WriteLine(n.ToString());
    });
}


っていう書き方ができるんです。


イイ!イイ!イイ!激しくイイ!
こりゃ楽しいや。

int? - Nullable

一部でうわさになっていた機能ですが、VS2005 CTP March 2004 で実装されていたんですね。全然気付いてなかったです(^^;


本来、値型は null という状態をとることはできません。C# の int も System.Int32 構造体のエイリアスなので、当然、値型です。なので表現できるのは整数値のみで null というのは表現できません。もし、値型も null を取れるようにすると値型の意味合いがかなり大きく変わってしまいます。しかし、そんなことをしなくても Generics を使えば 「null も表現できる値型」 が作れます。それが Nullable です。そして、C# では int? と型宣言をすると自動的に Nullable とコンパイルしてくれます(なので int? は単なるシンタックスシュガー)。


まぁ、以下のコードを見てもらえばわかるでしょう。


注意:某所の情報によると Nullable はなくなることはないと思いますが、int? が正式採用されるかどうかはまだ微妙みたいです。



int? i = null;
?
// 型名を表示(Nullable!1 とのこと)
Console.WriteLine(i.GetType().Name);
?
// null か確認
if (!i.HasValue)
{
    Console.WriteLine("!HasValue");
}
?
// null が確認
// ちなみになぜこれで動くかというと op_Implicit、すなわち implicit operator T (Nullable) が定義されているから。
if (i == null)
{
    Console.WriteLine("null");
}
?
// たとえ !HasValue であっても参照できる
// これも op_Implicit のおかげ。
if (i != 0)
{
    Console.WriteLine("i != 0");
}
?
// ただし !HasValue のときに Value を参照すると InvalidOperationException
//if (i.Value != 0)
//{
//    Console.WriteLine("i.Value != 0");
//}
?
// 整数を代入
i = 1;
?
// HasValue はもちろん true
Console.WriteLine(i.HasValue);
?
// i だけで参照。これも op_Implicit のおかげ。
Console.WriteLine("{0:d}", i);
Console.WriteLine(i.ToString());
?
// Value で参照
Console.WriteLine("{0:d}", i.Value);
Console.WriteLine(i.Value.ToString());

2004年5月18日火曜日

ASP.NET でクライアントサイドのエンターキーを制御する

IE では、テキストボックスが 1つとボタンが 1つといった場合に、テキストボックスでエンターキー(改行キー)を押すと自動的に submit してしまうため、PostBack が発生してしまいます。
こいつを PostBack させないようにする方法です。


/// <summary>
/// エンターキーを制御するクライアントスクリプトを出力します。
/// </summary>
/// <param name="page">スクリプトを出力する<see cref="System.Web.UI.Page"/>。</param>
public static void RegisterEnterKeyPageScript(System.Web.UI.Page page)
{
    page.RegisterClientScriptBlock("enterkey",
        "<script language='javascript'>\n" +
        "function text_keydown(e, name)\n" +
        "{\n" +
        "  var key = 0;\n" +
        "  if (typeof(e.keyCode) != 'undefined') {\n" +
        "    key = e.keyCode;\n" +
        "  } else if (typeof(e.which) != 'undefined') {\n" +
        "    key = e.which;\n" +
        "  }\n" +
        "  if (key == 0xd) {\n" +
        "    if (typeof(name) != 'undefined' && name != '') {\n" +
        "      document.forms[0].elements[name].click();\n" +
        "    }\n" +
        "    return false;\n" +
        "  }" +
        "  return true;" +
        "}" +
        "</script>");
}
 
 
/// <summary>
/// エンターキー押し下げ時にサブミットするボタンを設定します。
/// name が "" のときはエンターキーを無視します。
/// </summary>
/// <param name="control">設定する<see cref="System.Web.UI.WebControls.WebControl"/>。</param>
/// <param name="name">サブミットするボタンの name。</param>
public static void RegisterEnterKeyScript(System.Web.UI.WebControls.WebControl control, string name)
{
    control.Attributes["onkeydown"] = "return text_keydown(event, '" + name + "');";
}

まずはこんなメソッドをどこかに用意しといてください。
で、テキストボックスが TextBox1、ボタンが Button1 とすると、Page_Load イベントで


RegisterEnterKeyPageScript(this);
RegisterEnterKeyScript(TextBox1, "");

と呼び出してやればエンターキーが無効になるはずです。
また、


RegisterEnterKeyPageScript(this);
RegisterEnterKeyScript(TextBox1, "Button1");

としてやれば、テキストボックスでエンターキーを押すと Button1 をクリックしたことになるはずです。


"はず" なんて書いているのは、これらの動作は ASP.NET は関係なくて完全にクライアントのブラウザに依存するからです。実際、上記のメソッドはクライアントサイドの JavaScript を出力してるだけです。なので、JavaScript がオフにされてると上記のコードは動きません。それと、IE6 とと Netscape6 あたりなら動くと思いますが、他のブラウザはどうかわかりません。
(「こうしたほうがいいよ」 ということがあったらコメントでもつけてください)

2004年5月13日木曜日

.NET でシリアル通信を使う(覚え書き)

Whidbey では標準でサポートされますが、現状の .NET Framework 1.0、1.1 にはシリアル通信(シリアルポート(Serial Port)の RS-232C とかでモデムを繋いだりするやつのことね)のサポートがないんですよね。
といっても、Win32 ではシリアルポートってあまり特別な存在じゃなく、CreateFile して SetCommState でごにょごにょして、あとは WriteFile とか ReadFile とかして...って感じなので DllImport すれば .NET でだって使えるわけです。


と言っても、すでにそれらをラップして便利に使えるようにしてくれたソースがいろいろと公開されています。なので、それの覚え書き。
なお、以下はちょこっとソースを見ただけで、詳しく調べたわけじゃないのでコメントは間違ってるかもしれません。


MSDN Magazine 「Use P/Invoke to Develop a .NET Base Class Library for Serial Device Communications」
http://msdn.microsoft.com/msdnmag/issues/02/10/netserialcomm/

まぁ、標準的な実装なのかな?Win32 API をラップして使いやすくしたクラスが用意されてる。


The Code Project 「Serial Communications : The .NET Way」
http://www.codeproject.com/dotnet/DotNetComPorts.asp

こちらも上のと同じような感じかな?


GotDotNet User Sample 「SerialPort component and CSTerm terminal application」
http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=b06e30f9-1301-4cc6-ac14-dfe325097c69

これは Form に貼り付けて使うという使い方ができるようになってるみたい。お手軽かも。


GotDotNet User Sample 「SerialStream - use the serial port as a Stream」
http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=FCBA7FC5-666E-4EB0-863F-0045B0C79EC7

おっ、これはおもしろいかも。Stream を継承して SerialStream を作ってある。ちゃんと BeginRead/Write などの非同期メソッドもある。

2004年5月7日金曜日

.Text から PING.BLOGGERS.JP さんにも ping を送るようにする

もともと .Text では http://www.weblogs.com/ に ping を送る(※1)ようになっています。(web.config でオフにすることもできます)
ちなみに、http://www.weblogs.com/ を IE6 で見ると日本語が文字化けしてますが、「表示」-「エンコード」 メニューで utf-8 を選択すればそれなりに見えるようになります。


※1 プロトコルの仕様はこちら。Weblogs.Com XML-RPC interface


で、この処理を行っているのは Dottext.Framework\Tracking\WeblogsNotificatinProxy.cs なんですが、実装方法がちょっと変わっています。Attribute で送信先 URL や Method を指定するようになっています。これは XML-RPC.NET の CookComputing.XmlRpc.dll を使って実装しているようです。


というわけで 「WeblogsNotificatinProxy.cs をまねして http://ping.bloggers.jp/rpc/ に ping を送るクラスを作る」 というのが一番楽そうだったのでそうしてみました。


追加・変更したソースを http://www.divakk.co.jp/aoyagi/BloggersJpNotificatinProxy.ZIP においておきます。
BloggersJpNotificatinProxy.cs (と .resx)が WeblogsNotificatinProxy.cs をまねして新規に作ったクラスです。
Notification.cs は 3行だけ追加してあります。
これらの追加・変更を行ってビルドすれば PING.BLOGGERS.JP にも ping を送るようになります。


一応、ビルドした DLL を http://www.divakk.co.jp/aoyagi/dotText_bin.ZIP においておきます。この DLL は、私のところで動いているものと同じですので Trackback ping の utf-8 化などの修正も行ってあるものです。

2004年5月6日木曜日

PING.BLOGGERS.JP さんに ping を送ってみる

PING.BLOGGERS.JP さんに ping を送るようにしてみました。


が、これであってるのかどうか今ひとつ自信がありません。ちゃんとできているようなら改造方法を公開します。(ソースを改造してビルドしなおさないとダメなんですが)

.Text のインラインコメント化

.Text のインラインコメント表示についてです。
(インラインコメントっていうのは私が勝手にそう呼んでるだけです。ここでやってるように各 Post の下にコメントやトラックバックも表示することをそう呼んでます)


原水商店さんの .Text Blogs 日本語 Skin から頂いたスキンをインラインコメント化したものを置いておきます。
http://www.divakk.co.jp/aoyagi/SkinsJP_IC.zip


インラインコメント化スキンの使用方法



  1. InlineComments.cs を Skins フォルダにコピーしてください。
  2. 各スキンを Skins フォルダにコピーしてください。インラインコメント化したスキンはスキン名(スキンのフォルダ名)の末尾に "_IC" をつけてありますので、従来のスキンと重なることはありません。
  3. Admin\Skins.config ファイルを適当に変更してください。サンプルを同梱してあります。なお、同梱した Skins.config は .Text Blogs 日本語 Skin とインラインコメント化スキンをあわせて使った場合の config になっています。こうしておくと普通のスキンとインラインコメント化したスキンのどちらでも選べるようになります。






以下に簡単ですがインラインコメント化する方法を書いておきます。
(簡単というよりほとんど覚え書きのような状態ですが)


InlineComments.cs を Skins フォルダにコピー。
(ソースコードによるコードビハインド。ソースコードにしたのは DLL を作り直さなくてもいいようにするため)


各スキンのインラインコメント化



  1. Comments.ascx をコピーして InlineComments.ascx を作る。
  2. InlineComments.ascx の 1行目の Inherits="Dottext.Web.UI.Controls.Comments" をInherits="Dottext.Web.UI.Controls.InlineComments" に変更。また、Src="..\..\InlineComments.cs" を追加。
  3. Day.ascx に <%@ Register TagPrefix="uc1" TagName="InlineComments" Src="InlineComments.ascx" %>を追加。<%@ Import Namespace = "Dottext.Framework.Components" %> を追加。適当な場所に を追加(CommentDisplayCount で最大いくつのコメントをインライン表示するか設定可能)。

これで一応は動くはず。
あとは見栄えがよくなるように InlineComments.ascx を修正する。
たとえば




  • <a name = "feedback" /> を削除。


  • <h3>フィードバック</h3> を削除。


  • <div id="comments"> を <div class="inlinecomments"> に変更。


  • <asp:Literal ID = "NoCommentMessage" Runat ="server" /> を削除。


  • HeaderTemplate を追加して見出しを表示。


  • ToTrackbackText を追加してトラックバックかどうかを表示するようにする(このために <%@ Import Namespace = "Dottext.Framework.Components" %> を追加する必要あり)。

など。
その上で Style.css に適当な CSS を追加。

2004年4月27日火曜日

各記事の下に Trackback URL を表示するようにする

「各個別記事の下に TrackBack URL を表示するようにしてみました」
に書いた件なんですが、「.Text にどういう修正を加えたか」を書くのをすっかり忘れてました。

ソースコードの修正は必要ありません。スキンの修正だけです(というか、スキンの修正だけで済むようにしてみました)。各スキンに ViewPost.ascx がありますが、これに修正を加えます。以下、例として Simple スキンを使いますが、他のスキンでも基本的に同じです。

ViewPost.ascx の改造

<%@ Control Language="c#" Inherits="Dottext.Web.UI.Controls.ViewPost" %>
<%@ Import Namespace = "Dottext.Framework" %>
<%@ Import Namespace = "Dottext.Framework.Components" %>
<%@ Import Namespace = "Dottext.Framework.Util" %>
<%@ Import Namespace = "Dottext.Common.Data" %>
<script Runat="server">
private string GetTrackBackUrl() {
    Entry entry = Cacher.GetEntryFromRequest(Context,CacheTime.Short);
    if (entry != null) {
        return "トラックバックは下記のURLにpingを送信してください。<br/>\nTrackBack URL: " + CurrentBlog.UrlFormats.TrackBackUrl(entry.EntryID);
    }
    return "";
}
</script>
<div class = "singlepost">
    <div class = "posttitle">
        <asp:HyperLink  CssClass="singleposttitle" Runat="server" ID="TitleUrl" />
    </div>
    
    <asp:Literal id="Body"  runat="server" />
    <div class = "itemdesc">
        投稿日時 : <asp:Literal id="PostDescription"  runat="server" />
    </div>
</div>
    <div class="trackbackurl"><% Response.Write(GetTrackBackUrl()); %></div>
    <asp:Literal ID = "PingBack" Runat = "server" />
    <asp:Literal ID = "TrackBack" Runat = "server" />

太字の部分が追加した行です(追加だけで既存部分の修正は必要ありません)。
あとは、Style.css にお好みの CSS を設定しておくだけです。


Style.css(私が使っている CSS)

.trackbackurl
{
    border: 1px solid #DDDDDD;
    background-color: #DDDDDD;
    padding: 4px;
    font-size: 14px;
}

2004年3月30日火曜日

Web.config に IConfigurationSectionHandler を使って独自の設定項目を追加 する

IConfigurationSectionHandler を使うと Web.Config に簡単に独自の設定を追加することができます。




MyConfig クラス

using System;
using System.Configuration;
using System.Xml;
using System.Xml.Serialization;
 
namespace WebApplication1
{
    [Serializable]
    public class MyConfig : IConfigurationSectionHandler
    {
        public object Create(object parent, object configContext, System.Xml.XmlNode section) 
        {
            XmlSerializer ser = new XmlSerializer(this.GetType());
            return ser.Deserialize(new XmlNodeReader(section));
        }
 
        public MyConfig()
        {
        }
 
        public static MyConfig Instance()
        {
            return (MyConfig)ConfigurationSettings.GetConfig("MyConfig");
        }
 
        private string _strParam = "*";        // default: "*"
        public string StrParam
        {
            get { return _strParam; }
            set { _strParam = value; }
        }
 
        private bool _boolParam = true;        // default: true
        public bool BoolParam
        {
            get { return _boolParam; }
            set { _boolParam = value; }
        }
 
        private int _intParam = 10;            // default: 10
        public int IntParam
        {
            get { return _intParam; }
            set { _intParam = value; }
        }
    }
}



Web.config



<configuration>

    <configSections>

        <section name="MyConfig" type="WebApplication1.MyConfig, WebApplication1"/>

    </configSections>

 

    <MyConfig>

        <StrParam>abc</StrParam>

        <BoolParam>false</BoolParam>

        <IntParam>5</IntParam>

    </MyConfig>

</configuration>




こういう風にしておくと読み込みの際に MyConfig.Create が呼ばれるので XmlSerializer を使ってデシリアライズしてあげるわけです。
使うときはこんな感じ


Label1.Text = MyConfig.Instance().StrParam;

Label2.Text = MyConfig.Instance().BoolParam.ToString();

Label2.Text = MyConfig.Instance().IntParam.ToString();


ちなみにデシリアライズされた結果はキャッシュされているようで MyConfig.Instance() するたびにデシリアライズが実行されるということはありません。
あと、たとえば int 型の項目に "abc" とかって指定するとデシリアライズ時に例外が発生するのでエラーページが表示されることになります。

2004年3月26日金曜日

Visual Studio 2005 Community Technology Preview March 2004 - Full DVD Image (English)

おおっ、すでに MSDN Universal Downloads に上がってました。


PDC で配布されたのは 2003/08 くらいのビルドだったと思いますが、どのくらい変わってるんでしょうね。まぁ、ダウンロードしてみればわかるわけですが。って、今ダウンロード中だけどあと 10時間もかかるよ(^^;

2004年3月25日木曜日

Visual Studio 2005 Community Technology Preview

http://blogs.msdn.com/jledgard/archive/2004/03/23/94690.aspx


ちょうど今行われている VS Live! San Francisco で VS 2005 Tech Preview が配布される模様。


MSDN Universal Subscriber Downloads な人には近いうちにこの Preview にアクセスする方法についてインフォメーションがある模様(ということはダウンロードできるようになる?)。


早くも "Whidbey" ではなく "VS 2005" として登場するみたいですね。

2004年1月28日水曜日

USERS GROUP 日記さん

.Text を使った blog サイトの紹介
USERS GROUP 日記


.Text を Multiple で使っていて複数の方の blog が集約されています。それぞれの方の blog へは左側にある "BLOGGERS" のところからいけます。


以下はトラックバックのテストです(^^
http://blogs.users.gr.jp/haramizu/archive/2004/01/28/966.aspx

2004年1月27日火曜日

各個別記事の下に TrackBack URL を表示するようにしてみました

一色さんの #BLOG
青柳臣一blogさん、「.TEXT」のトラックバック対応方法を公開


にてご指摘があったので、各個別記事の下に TrackBack URL を表示するようにしてみました。こんな感じでいかがでしょう?


# たぶんバグってないとは思うんですが...


ちなみに #BLOG さんの Movable Type も Auto-Discovery 用のコメントは入っています。なので、.Text からもちゃんとトラックバックできるはずです。
(この書き込みはそのテストも兼ねてたりします :-) )

すぐ下の記事にトラックバックしてみます

やっぱり言葉でうまく表現できなかったので、サンプルとしてすぐ下の記事にトラックバックしてみます。
http://www.divakk.co.jp/blog/aoyagi/archive/2004/01/27/442.aspx
こんな風にリンクをはるだけです。


で、Excerpt には


これが Excerpt に書いた内容です。どんな風に表示されるかな?

と書いて POST しました。

.Text のトラックバック

あらためて説明しなくとも、Google あたりで 「トラックバックとは」 とかのキーワードで検索するとたくさん出てきます。なので、一般論はそちらにお任せしちゃいます。
ここでは、.Text を使っている場合のトラックバックについて書きます。


.Text でトラックバックするには?


実は何もする必要がありません。記事を書くときに単に PermaLink のリンクを含めるだけで OK です。(PermaLink っていうのは、各記事への URL のことです。たとえば、この記事だと http://www.divakk.co.jp/blog/aoyagi/archive/2004/01/27/442.aspx になります)


PermaLink が含まれた記事を POST すると、自動的にトラックバックを送ります(もちろん、相手がトラックバックを受けれる blog じゃないとダメですが。詳細は後述)。


ただ、1つだけ気をつけたほうがいいことがあります。
トラックバックのときに相手先に送る情報は、



  • title … 記事のタイトルです。たとえば、この記事だったら 「.Text のトラックバック」 です。

  • excerpt … 英単語の意味は引用とか抜粋とかですが、まぁ、コメントだと思ったらいいです。

  • url … 自分の URL です。トラックバックする元、たとえば、この記事が PermaLink を含んでいるとしたら、この記事自身の URL です。

  • blog_name … そのまんま blog の名前です。ここだったら 「青柳臣一 blog」 ですね。

  • (あと "charset=utf-8" も含めようという方向になってます。が、まだ Trackback 仕様書には載ってないです)

があります。ここで、title、url、blog_name は問題ないんですが、excerpt がちょっと問題です。.Text では Excerpt が記入されていない場合は、単にタイトルを送っちゃいます(title と excerpt が同じものになります)。
じゃ、Excerpt はどこで記入するのかというと、POST のページの下のほうにある "Advanced Options" を開くと出てくる Excerpt です。なので、記事中に PermaLink へのリンクがある場合はここにコメントを書きましょう。するとこれが相手先に送られます。


トラックバックするとどうなるのか?


ここでは、トラックバックする相手も .Text だとします。
.Text では、コメントやトラックバックをひっくるめて Feedback と呼んでいます。こちらからある記事にトラックバックすると、相手の記事の Feedback のところに表示されるようになります。見た目はコメントとほとんど区別できません。ただ、Excerpt に書いた内容がコメントとして表示され、自分の記事への URL がリンクされます。(うーん、言葉で書くのが難しい(^^; )


まぁ、結局、トラックバックっていうのは 「自動コメント&自動逆リンク」 なわけです。


ところで、私はトラックバックかどうかを簡単に見分けられたほうがいいかな?と思って "(トラックバック)" と表示されるようにスキンを変更してます。


仕組みは?


ほんとうは、PermaLink の URL とトラックバック用の URL は別物です。ではなぜ PermaLink だけからトラックバックできるんでしょう?


実は各記事にはトラックバックの URL がわかるようにコメントが埋め込んであります。
HTML のソースを見ると


<!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
rdf:about="http://www.foo.com/archive.html#foo"
dc:identifier="http://www.foo.com/archive.html#foo"
dc:title="Foo Bar"
trackback:ping="http://www.foo.com/tb.cgi/5" />
</rdf:RDF>
-->

なんて感じのが見つかります。これの trackback:ping 属性がトラックバック用の URL です。
このように HTML 中にコメントとしてトラックバックの URL を埋め込んで自動的にトラックバックできるようにすることを Auto-Discovery というようです。
http://www.movabletype.org/docs/mttrackback.html#autodiscovery of trackback ping urls


.Text は記事を POST する処理の中で、



  1. 記事中に PermaLink があるかどうか探す。

  2. あったら、そのリンク先を HTTP GET してみる。

  3. GET できたら、その HTML 中に trackback:ping があるか探す。

  4. あったら、そこへトラックバックする。

  5. 以上を記事中のすべての PermaLink について繰り返す。

といった処理を行っています。
そんなわけで PermaLink へのリンクを含めるだけで、自動的にトラックバックしてくれるわけです。


というように、.Text 自身が Auto-Discovery を使うことを前提にしているので、どこにもトラックバック用の URL が表示されてないんですよね。これは、どっかに表示するようにしようと思います。


ところで、「おいおい 2~4 って HTTP のやり取りだろ。重いんじゃないの?」 とお思いの方もいるかとは思いますが、.Text ではこの部分はちゃんと ThreadPool を使って別スレッドで行うようになっています。

2004年1月26日月曜日

.Text の修正(トラックバック関連)

.Text はトラックバックに対応してるんですが、日本語を使ってるとうまく動きません。
文字化けするとかいう次元じゃなく、トラックバックを送る途中で例外が出て失敗しちゃいます。





Dottext.Framework\Tracking\Notification.cs 81行目付近
    if(entry.HasDescription)
    {
        notify.Description = entry.Description;
    }
    else
    {
        //entry.Description = entry.Title;    
        notify.Description = entry.Title;    
    }
上記のように entry.Description = entry.Title; というのは明らかにおかしいので notify.Description = entry.Title; に修正。





Dottext.Framework\Tracking\TrackBackNotificationProxy.cs 81行目付近
    //string parameters = "title=" + HtmlEncode(title) + "&url=" + HtmlEncode(link) + "&blog_name=" + HtmlEncode(blogname) + "&excerpt=" + HtmlEncode(description);
    string parameters = "title=" + HttpUtility.UrlEncode(Encoding.UTF8.GetBytes(title))
                      + "&url=" + HttpUtility.UrlEncode(link)
                      + "&blog_name=" + HttpUtility.UrlEncode(Encoding.UTF8.GetBytes(blogname))
                      + "&excerpt=" + HttpUtility.UrlEncode(Encoding.UTF8.GetBytes(description))
                      + "&charset=utf-8";
もともとのコードはまったく文字コードのことを考えてない。なので、utf-8 に変換してやるように修正。ここが例外が出る原因で、utf-16 のままだと String.Length と実際に送信するバイト数が違うために失敗してしまいます。
ちなみに、下記のように「トラックバックは utf-8 でいいんじゃないの?」という方向のようですので、とりあえずはこれでいいんじゃないかと思います。

Milano::Monolog 「Trackbackの文字コード指定方法最終(予定)」
http://rebecca.ac/milano/mt/archives/000396.html

BlogX から .Text へのデータインポート

原水さんのところで知ったんですが、BlogX から .Text へデータをインポートするためのツール into .Text っていうのがあります。http://blogs.users.gr.jp/haramizu/archive/2004/01/20/807.aspx
しかし、残念ながら .Text 0.94 用で 0.95 だとデータベースが変わっているためにそのままでは使えませんでした。そこで、0.95 対応に修正してみました。また、ついでにカテゴリも自動的にインポートするようにしてみました。


改造版の into .Text は こちら。
ソースとバイナリが両方入っています。


オリジナルの into .Text
ソース http://postback.be/postback/posts/216.aspx
バイナリ http://postback.be/postback/posts/213.aspx

.Text に変更しました

久しぶりの更新です。


今まで BlogX を使ってましたが、.Text に変更しました。

2003年11月27日木曜日

PDC 2003 のストリーミングが公開


http://microsoft.sitestream.com/PDC2003/



PDC 2003 の各セッションの内容がストリーミングで公開されています。ストリーミングといっても、画像は PowerPoint のスライドです。音声は PDC で録音されたものです(拍手の音とか笑い声とかもちょっと入ってます)。
ちなみに、http://microsoft.sitestream.com/ は
TechEd 2003 のストリーミングが公開されていたところですね。

2003年11月13日木曜日

"Windows Longhorn Client Preview" on MSDN Subscriber Downloads


MSDN Subscriber Downloads で "Windows Longhorn Client Preview"なるものがダウンロードできるようになっています。
Longhorn SDK もある。

2003年11月5日水曜日

PDC 2003 DVD Kit


PDC 2003
DVD Kit



こちらで、PDC 2003 のストリーミングファイルやスライドを収録した DVD が購入できます。
Country に Japan もあるから日本からも買えるみたいです。けど、$499 + 送料はちと高いなぁ。

無料で公開してはくれないんだろうか?

Visual Studio .NET Framework Bootstrapper プラグイン 日本語版 (アルファ 版)


Visual
Studio .NET Framework Bootstrapper プラグイン 日本語版 (アルファ版)



Visual Studio.NET 2003 のセットアッププロジェクトで .NET Framework 再領布モジュール込みの setup.exe を作れるようにするプラグインです。当然、setup.exe
が 24メガバイトくらい大きくなると思いますが、CD-ROM などでアプリケーションを配布する場合とかは便利かも。