Read habradigest_07.pdf text version

2009

7

Ruby

habradigest 7 · 2009 i

habradigest 7 · 2009

ii

2009 7

, ! - . : 20 99 . , , , Ruby. . Ruby, , MaxEcl. . Ruby , : LaTex, JavaScript, .ET, yt , ET, , . asLayut Iteret Explrer aya. , Liquid Resize Ktter. , . smira memcaced . .

"XaocCPS"

LATEX LaTeX. PGF/TikZ Liquid Resize .NET IronPython .NET LINQ to SQL SQL Server Unity: DI/IoC & AOP Microsoft Object Builder Use Case Driven Development Composite UI Application Block - PYTHON -- , .. Python WEB- IE. hasLayout memcached/MemcacheDB JAVASCRIPT JavaScript: JavaScript RUBY Ruby ! DSL Ruby Ruby, Ruby on Rails 99 72 88 91 94 64 70 51 55 39 42 46 34 15 18 22 26 30 13 6 2

habradigest 7 · 2009

1

LATEX

LaTeX. PGF/TikZ

adrianopol

. LaTeX, PGF TikZ, Xy-pic :-).

- , , , , - . picture ; Stricks stScript ( pdflatex, ), -, GF; Metast, , , . , GF/TikZ. , «pgf examples» . : www. texample.et/tikz/examples/all. , . , . pgf/tikz LaTeX, , pgf/tikz . TikZ & GF. Maual fr Versi 2.00 (560 .). . , Guidelies Grapics (. 65), , , ; , pgf/tikz - .

GU/Liux pgf ( xclr >= 2.00). , ( ) texas ( . ). Widws pgf/tikz MiKTeX, .

pdf

pdflatex file.tex

ps :

latex file.tex dvips file.dvi

. , , , . , - , . habradigest 7 · 2009

HTML SVG.

\usepackage{tikz}

2

LATEX

pgf/tikz \tikz ( ), \begi[ptis]{tikzpicture}...\ed{tikzpicture}. \tikz , (\tikz[ptis]{...}). .

\documentclass{memoir} \pagestyle{empty} \usepackage{tikz} \begin{document} \tikz{\draw (-1,-1) -- (1,1); \path[fill=green!80!bl ue,draw=red] (0,0) circle (7mm);} \end{document}

, (. ), . (, ). ( ) ( ).

\begin{tikzpicture} \draw[help lines] (0,0) grid (3,2); \draw (0,0) coordinate (A) -- (3,2) coordinate (B) (1,2) -- (3,0); \fill[red] (intersection of A--B and 1,2--3,0) circle (2pt); \end{tikzpicture}

, . .

. : -- (2,0) -- ( -- 1 ); -- (2cm,-3pt) -- 2 Ox, ­3 Oy; -- (30:5cm) -- 5 30 ; -- +(2,0) -- , 2 ( ); -- ++(2,0) -- , 2 , .

\tikz \draw (0,0) -- +(1,0) -- +(0,1) -- +(1,1); \tikz \draw (0,0) -- ++(1,0) -- ++(0,1) -- ++(1,1); \tikz \draw (1,0) -- (0,0) -- (30:1);

. : -- crdiate!umber!agle:secd_crdiate -- crdiate!dimesi!agle:secd_crdiate -- crdiate!prjecti_crdiate!agle:secd_ crdiate , -- (1,2)!.25!(3,4) , (1,2)

habradigest 7 · 2009

3

LATEX

(3,4) -- (1,2)!1cm!(3,4) , 1 (1,2) (1,2)--(3,4) -- (1,2)!(0,5)!(3,4) , (0,5) (1,2)--(3,4)

(1,1) node [above right] {$C$} -(0,1) node [above left] {$D$} -cycle; \end{tikzpicture}

-- . \pat. , , . draw, fill, sade, clip . \pat[draw], \pat[fill], \pat[sade,draw],... \draw, \fill, \sadedraw. -- (a) -(b), (a) (b) -- . (a) .. ctrls (x) ad (y) .. (b), (a) (b) -- , (x) (y) -- , . ad (y) , , (y) = (x).

scpe ; . , tikzpicture scpe. .

\tikz \draw (0,0) -- (1,1) {[rounded corners] -- (2,0) -- (3,1)} -(3,0) -- (2,1);

( LaTeX) -: key=value. , \tikz \draw[lie widt=2pt,clr=red] (1,0) -- (0,0) -- (1,0) -- cycle;. key= , .

(des). ( ), . ( : , , ..), (, , , ...), (, ) .

\tikz \draw (1,1) node {text} -- (2,2);

. , . .

\begin{tikzpicture}[scale=0.7] \draw (0,0) grid +(2,2); \draw[help lines] (3,0) grid +(2,2); \end{tikzpicture}

\begin{tikzpicture}[line width=2pt] \draw (0,0) node [below left] {$A$} -(1,0) node [below right] {$B$} --

habradigest 7 · 2009

4

LATEX

calc

\usetikzlibrary{calc}

, ,

\begin{tikzpicture}[scale=0.5] \draw[help lines] (0,0) grid (4,3); \fill [red] ($2*(1,1)$) \fill [green] (${1+1}*(1,.5)$) \fill [blue] ($cos(0)*sin(90)*(1,1)$) \fill [black] (${3*(4-3)}*(1,0.5)$) \end{tikzpicture}

circle circle circle circle

(2pt); (2pt); (2pt); (2pt);

(, , ), , , pgf/tikz. -- . ( ), ; . , . S. :

$ latex qq.tex && dvips -K -o qq.ps qq.dvi && convert -antialias -seed 0 -density 200 -trim qq.ps qq.png

habradigest 7 · 2009

5

Liquid Resize

Kotter

Liquid Resize, . ,

Seam Carving?

Seam Carvig -- , ( -- Ctet-Aware Image Resizig Algritm). 2007 . , . : ? -- , , , , . : , . . , , . , , - .

-, , . -. C#/. ET. / . « », . . -. , . . . , - -- . . , , , ...

: 1. . , -- , . 2. , , . -- , , . , . 3. , , , , . 6

. -. «», . , «eergy». . -- . -. -. habradigest 7 · 2009

.

, . «» -- - ( ), , . : ( ) ( ). , , . . :

: -- 8, -- 3. -- (8+3)/2 = 5.5. , , . 5. . , , . , 0. , , . :

, , . : . -- . . . 33 :

, R, G, B, . :

-- . : ( ), .

private void FindEnergy() { for (int i = 0; i < imgHeight; i++) for (int j = 0; j < imgWidth; j++) { energy[i, j] = 0; // R, G, B for (int k = 0; k < 3; k++) { int sum = 0, count = 0; // , sum

habradigest 7 · 2009

7

if (i != imgHeight - 1) { count++; sum += Math.Abs((int)image[i, j, k] - (int) image[i + 1, j, k]); } // , sum if (j != imgWidth - 1) { count++; sum += Math.Abs((int)image[i, j, k] - (int) image[i, j + 1, k]); } // energy k- ( R, G B) if (count != 0) energy[i, j] += sum / count; } } }

, «» , . ? / , , , . : ? -- , , . , , , :) , , . -- . . , «» ( «» ), . - , « » -- , . , . , . . :

: eergy -- , image -- , .

, . / , , . . , . , «». «» -- , , 1 , «» , .

-- . , 1 ( ):

1. «»

2. «»

habradigest 7 · 2009

8

. , . . : -- 8; -- 6; -- 7; (6) (6). 12. . :

eergy -- , sum -- , . , , -- ? -- . : , , . ? , . , . , . :

, : , . , 3 : -, -. , . , . :

s -- , e -- . :

private void FindSum() { // sum energy for (int j = 0; j < imgWidth; j++) sum[0, j] = energy[0, j]; // (i,j) sum // energy[i,j] + MIN ( sum[i-1, j-1], sum[i-1, j], sum[i-1, j+1]) for (int i = 1; i < imgHeight; i++) for (int j = 0; j < imgWidth; j++) { sum[i, j] = sum[i - 1, j]; if (j > 0 && sum[i - 1, j - 1] < sum[i, j]) sum[i, j] = sum[i - 1, j - 1]; if (j < imgWidth - 1 && sum[i - 1, j + 1] < sum[i, j]) sum[i, j] = sum[i - 1, j + 1]; sum[i, j] += energy[i, j]; } }

, -- , . :

: habradigest 7 · 2009 9

:

private int[] FindShrinkedPixels() { // int last = imgHeight - 1; // int[] res = new int[imgHeight]; // sum, res[last] res[last] = 0; for (int j = 1; j < imgWidth; j++) if (sum[last, j] < sum[last, res[last]]) res[last] = j; // . for (int i = last - 1; i >= 0; i--) { // prev - // (prev-1), prev (prev+1), int prev = res[i + 1]; // , sum, , , res[i] res[i] = prev; if (prev > 0 && sum[i, res[i]] > sum[i, prev - 1]) res[i] = prev - 1; if (prev < imgWidth - 1 && sum[i, res[i]] > sum[i, prev + 1]) res[i] = prev + 1; } return res; }

i- crpixels , i- . : , , , . . 1 , , , ( ). , 1 . , 1 , , , .

, , . , -- , , «». :

, , , . , , : , , , . , , 2 ?

, -, , c . . -- . , , . 1 , : , , . :

for (int i = 0; i < imgHeight; i++) for (int j = cropPixels[i]; j < imgWidth; j++) { pImage[i, j] = pImage[i, j + 1]; }

-- , , , , . , : , , 10

habradigest 7 · 2009

« » , «». , ? -- , - . -- , , 50%. , , , , . , :

4. «»

() () ()

5. . , .

() () () , , . , gmm .

, , , . .

() () ()

() () ()

, :

3. Content-Aware Resizing'

-- 11

habradigest 7 · 2009

, Seam Carvig; -- , ( tsp ttp://rsizr.cm/, ); -- ( , , , ); -- , Ctet-Aware Rescale tsp , , . , , .

P. S.

(VS 2008) (.ET) : -- DF, (, ~18 ). -- Sbl peratr(). -- . , , , . -- prkudie , : · Liquid Rescale GIM ImageMagick, liblqr, · SeamCarvigGUI CAIR

habradigest 7 · 2009

12

stboris

( ) /. , ( god, sex, love). , .. , , . , , , .

- , - « , ». 4 , . -- . , : , , , , . , , , (, , ). , . . / (-, -, - ..) ( ) . , .. . ­ , ( , , ..). , . , ­ . -- . -- aubergie

, , .

. . : -- , , . . -- AUBERgie

, - « » ( , ). .

, .. . , , / , . «»

. . . - - , . , [email protected], e=3, i=! .. -- , , .. , ­ . , .. - , 13

( ), . habradigest 7 · 2009

«» . @=2, !=1 .. . -- @UB3Rg!3 , . -- 2UB3Rg13

«» «» . (, ) «». , . , Aurvte Arc Liux , «$». «» , «» -- . «» «1» «» «)». -- [email protected]!3) , -- , , .

, . . - , . , , , .

, .. , , , .

, , ( , , ), ( , ).

, =) , , .. / -/ , . .

, , ( ). , , .. , , . ­ , , , .

. habradigest 7 · 2009 14

.ET

IronPython .NET

alek_sys

, -- .NET -- API ? , IronPython -- Python .NET.

, -- «» -- , AI. .. , -- ru-time, . , -. -- - .ET ( C#) -- Reflecti. -- .ET (DLR) -- Iryt IrRuby. + .ET iterperability -- , . -- Reflecti. , -- -- .ET . -- -- -- DLR . Iryt ( :). Iy -- 2.0, cdeplex.cm/Iryt . , «tepad». «» «». -- «Macrses» .

private void Main_Load(object sender, EventArgs e) { MacrosToolStripMenuItem itm = null; string[] files = Directory.GetFiles(@».\ Macroses»); foreach (string file in files) { itm = new MacrosToolStripMenuItem(Path.GetFileN ameWithoutExtension(file)) { MacrosFileName = file }; itm.Click += new EventHandler(macroToolStripMen uItem_Click); ToolStripMenuItem.DropDownItems. Add(itm); } } internal class MacrosToolStripMenuItem : ToolStripMenuItem { public MacrosToolStripMenuItem(string FileName) : base(FileName) { } public string MacrosFileName { get; set; } }

MacrsTlStripMeuItem -- - TlStripMeuItem MacrsFileame , , textBx' e-mail «[email protected]». Macrses SaveEmail.py, -- , SaveEmail. -- Iy . Iryt.dll. MacrRuer -- .

public class MacroRunner { public static Form CurrentForm;

habradigest 7 · 2009

15

.ET

public string FileName { get; set; } public MacroRunner() { } public void Execute() { // Python- IronPython.Hosting.PythonEngine pyEngine = new IronPython.Hosting.PythonEngine(); // - , .. // , pyEngine.LoadAssembly(System.Reflection.Assembly. GetExecutingAssembly()); try { pyEngine.ExecuteFile(FileName); } catch (Exception exc) { MessageBox.Show(exc.Message); } } }

SaveEmail.py -- . , -- SaveEmail.py:

from Notepad import * import re text = MacroRunner.CurrentForm.textBox.Text links = re.findall(«\w*@\w*\.\w{2,4}», text) file = open(«emails.txt», «w») file.write(«\n».join(links)) file.close()

.. -- tepad -- . MacrRuer -- ( -- , - -- AI). -- , email -- . , , email -- , , -- emails.txt. , -- . , Macrses UIMdifier.py. -- . -- . , WiFrms Iy System.Widws.Frms. -- LadAssembly. -- , Iryt . , :). AddReferece clr.

from Notepad import * main = MacroRunner.CurrentForm import clr clr.AddReference(«System.Windows.Forms») from System.Windows.Forms import * def pyHello(s,e): MessageBox.Show(«Hello from IPy!») item = ToolStripMenuItem() item.Name = «pybtn» item.Text = «Python created!» item.Click += pyHello main.ToolStripMenuItem.DropDownItems.Add(item)

-- Iy -- . , Iy tepad. , LadAssebmly -- System.Widws.Frms -- . ,

protected void macroToolStripMenuItem_Click(object sender, EventArgs e) { MacrosToolStripMenuItem item = sender as MacrosToolStripMenuItem; MacroRunner runner = new MacroRunner() { FileName = item.MacrosFileName }; MacroRunner.CurrentForm = this; runner.Execute(); }

-- Iy- , -- CurretFrm. tepad.MacrRuer.CurretFrm. , , , -- AI -- . -- textBx (Mdifier = ublic). , (Mdifier = ublic). , habradigest 7 · 2009

16

.ET

-- , System.Widws.Frms System.Widws.Frms -- . pyHell -- -- -- . , . :

«yt reated!» MessageBx -- , .

habradigest 7 · 2009

17

.ET

LINQ to SQL SQL Server

RollingStone

2008 ( ) MS SQL Server . ! , . , , : «» MySql PostGIS. c#, , , Microsoft. : , , , , . SQL Server. LINQ LINQ to SQL . .

. , msd, «LIQ t SQL: .ET Laguage-Itegrated Query fr Relatial Data». , « » . SQL Server : gemetry gegrapy. , , -- (/). , , - , SQL Server B-. «» . . MySql, , , R-, , . , -- , . , LIQ t SQL , , . , , , . , , , . , , . , , , , . , , - LIQ t SQL. :

USE ExampleDatabase; GO --Create table CREATE TABLE Boundaries_Country( FeatureID UNIQUEIDENTIFIER NOT NULL PRIMARY KEY, CountryName VARCHAR(100) NOT NULL UNIQUE, CountryBoundary GEOGRAPHY NOT NULL ) CREATE SPATIAL INDEX SpatialIndex ON Boundaries_Country (CountryBoundary); GO

.

11 CutryBudary c gegrapy, . , , sape- . -- , , , , . SQL Server ( 1).

LINQ to SQL

LIQ t SQL 18

habradigest 7 · 2009

.ET

, , gegrapy, , . . DataCtext, .

using System.Data.Linq; namespace MyNamespace { public class ExampleDatabase: DataContext { public Table<Boundaries_Country> BoundariesCountry; public ExampleDatabase(string connectionString) : base(connectionString) { } } }

1. - SQL Server

: System.Data.Liq Micrsft. SqlServer.Types. ( «.ET» «Add Referece» -- ), «C:\rgram Files\Micrsft SQL Server\100\SDK\Assemblies\». , «.ET» , gacutil. LIQ t SQL -- - . -- .

using System; using System.Data.Linq.Mapping; using Microsoft.SqlServer.Types; namespace MyNamespace { [Table()] public sealed class Boundaries_Country { [Column(AutoSync = AutoSync.OnInsert, DbType = "uniqueidentifier", IsPrimaryKey = true, IsDbGenerated = true, UpdateCheck = UpdateCheck.Never)] public Guid FeatureID; [Column(DbType = "varchar(100)", CanBeNull = false)] public string CountryName; [Column(/*DbType = "geography", */CanBeNull = false)] public SqlGeography CountryBoundary; } }

, , , , «».

static void Main(string[] args) { ExampleDatabase db = new ExampleDatabase(@»...»); var q = from item in db.BoundariesCountry where item.CountryName.StartsWith("C") select item; foreach (var item in q) Console.WriteLine(item.CountryName); }

:

. , 7, Table , . , , , , ame: [Table(ame = «Budaries_Cutry»)]. 16, , habradigest 7 · 2009

. 9 q, LIQ t SQL .

19

.ET

LINQ to SQL:

, , , «». (WKT-): OLYGO ((40 -28, 40 30, 5 30, 5 -28, 40 -28)).

var q = from item in db.BoundariesCountry where item.CountryName.StartsWith("C") && item.CountryBoundary. STIntersects(sqlEnvelope).Value select item; foreach (var item in q) Console.WriteLine(item.CountryName);

Boundaries_Country( [Parameter(DbType = "varbinary(max)")] byte[] boundingBox) { IExecuteResult execResult = this. ExecuteMethodCall(this, ((MethodInfo) (MethodInfo.GetCurrentMethod())), boundingBox); ISingleResult<Boundaries_Country> result = ((ISingleResult<Boundaries_Country>)execResult. ReturnValue); return result; }

, . , 5, LIQ t SQL , : «Metd `System.Data.SqlTypes. SqlBlea STItersects(Micrsft.SqlServer.Types. SqlGegrapy)' as supprted traslati t SQL.». table-valued , SQL Server' WKB.

, , . 4 execResult, , 5, . «» :

var q = from item in db.sp_bbx_Boundaries_Country( sqlEnvelope.STAsBinary().Buffer) where item.CountryName.StartsWith("C") select item; foreach (var item in q) Console.WriteLine(item.CountryName);

:

, .

CREATE PROCEDURE [dbo].[sp_bbx_Boundaries_Country] @boundingBox varbinary(max) AS BEGIN SET NOCOUNT ON; SELECT * FROM dbo.Boundaries_Country WHERE GEOGRAPHY::STGeomFromWKB(@boundingBox,4326). STIntersects(CountryBoundary) = 1; RETURN; END

, , , , . 1. , -. api, «» geeric- , , geeric-, - . 2. sql. geeric-, , ( ) - ( , ). 20

-- ( ) WKB-. 8 STGemFrmWKB gegrapy STItersects, . , , DataCtext ( ExampleDatabase), .

[Function()] public ISingleResult<Boundaries_Country> sp_bbx_

habradigest 7 · 2009

.ET

-- , LIQ t SQL, , : , , . .. SQL LIQ- . ilie SQL Server'.

Table-valued

Table-valued , , .

CREATE FUNCTION [dbo].[f_bbx_Boundaries_Country] ( @boundingBox varbinary(max) ) RETURNS TABLE AS RETURN ( SELECT * FROM dbo.Boundaries_Country WHERE GEOGRAPHY::STGeomFromWKB( @boundingBox, 4326). STIntersects(CountryBoundary) = 1 )

[Function(IsComposable = true)] public IQueryable<Boundaries_Country> f_bbx_Boundaries_ Country( [Parameter(DbType = "varbinary(max)")] byte[] boundingBox) { return this.CreateMethodCallQuery<Boundaries_ Country>(this, ((MethodInfo)(MethodInfo. GetCurrentMethod())), boundingBox); }

IsCmpsable, , SQL Server, . CreateMetdCallQuery. :

var q = from item in db.f_bbx_Boundaries_Country( sqlEnvelope. STAsBinary().Buffer) where item.CountryName.StartsWith("C") select item; foreach (var item in q) Console.WriteLine(item.CountryName);

, . ( liq sql-):

.. , . .

habradigest 7 · 2009

21

.ET

Unity: DI/IoC & AOP

butaji

- , IoC, DI, AoP, , , Microsoft Unity .

Inversion of Control (IoC) Dependency Injection (DI)

IC : * (Inversion of Control, IoC) -- - , . IoC Dependency Injection Principle. Dependency Injection framework'. Smalltalk, C++, Java .NET. * , IoC , , , « » DI : (. Dependency injection) « (. Inversion of control)», . , , , , . . , / ( , Factry, Registry). - IC DI , , - , , , . , .ET DI/ habradigest 7 · 2009

IC : -- Castle Widsr -- StructureMap -- Sprig.ET -- Autfac -- Uity -- uzzle.Factry -- iject -- S2Ctaier.ET -- icCtaier.ET -- LiFu

Aspect-oriented programming (AoP)

, : - () -- , , , . , - () , . , , , , . , - Decratr (.), , , . framewrk': -- stSarp -- Aspect.ET -- LOOM.ET -- uzzle.Aspect -- AspectDG -- Aspect# -- Ecase -- Cmpse* -- Seasar.ET -- DtSpect (.SECT) -- c The Sprig.ET Framewrk

22

.ET

Microsoft Enterprise Library

, 2008 Micrsft Eterprise Library 4.1, Uity Applicati Blck 1.2. Micrsft Eterprise Library patters & practices. Micrsft Eterprise Library , . -- - , « », . Micrsft Eterprise Library : -- Cacig Applicati Blck. . . -- Cryptgrapy Applicati Blck. . -- Data Access Applicati Blck. . -- Excepti Hadlig Applicati Blck. , . -- Lggig Applicati Blck. . -- licy Ijecti Applicati Blck. , , , , . -- Security Applicati Blck. . -- Uity Applicati Blck. , , depedecy ijecti , , , , . -- Validati Applicati Blck. -, .

Eterprise Library (EtLib) , , Eterprise Library. , Uity Applicati Blck EtLib : -- Uity Applicati Blck , EtLib. -- Uity Applicati Blck , ru-time . -- Uity Applicati Blck EtLib, EtLib. , , EtLib.

In Action.

: 1. .ET Framewrk 3.5 S1 2. IDE (tepad..Visual Studi 2008 S1) 3. Uity 4. 15-20

, CsleApplicati UityIActi1. : -- Micrsft.ratices.ObjectBulder2 -- Micrsft.ratices.Uity -- Micrsft.ratices.Uity.Itercepti. ILgger:

namespace UnityInAction1 { interface ILogger { void Write(string msg); } }

Lgger:

using System; namespace UnityInAction1 { class Logger : ILogger { #region ILogger Members public void Write(string msg) {

Unity Application Block

, depedecy ijecti , , , , . habradigest 7 · 2009

23

.ET

Console.WriteLine(); Console.WriteLine(«*** In logger ***»); Console.WriteLine(String.Format("message {0}", msg)); } #endregion } }

, . ILgger .ET:

namespace UnityInAction1 { interface ILogger { [Stopwatch] void Write(string msg); } }

:

using System; namespace UnityInAction1 { class Program { static void Main(string[] args) { ILogger logger = new Logger(); logger.Write(« »); Console.ReadKey(); } } }

Stpwatc:

using System; using Microsoft.Practices.Unity.InterceptionExtension; namespace UnityInAction1 { class Stopwatch : HandlerAttribute { public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container) { return new StopwatchCallHandler(); } } public class StopwatchCallHandler : ICallHandler { public int Order {get; set;} public StopwatchCallHandler() : this(0) {} public StopwatchCallHandler(int order) { Order = order; } #region ICallHandler Members public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); var result = getNext().Invoke(input, getNext); sw.Stop();

, IC/DI , Lgger ( , [ , , ] ):

using System; using Microsoft.Practices.Unity; namespace UnityInAction1 { class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); container.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager()); var logger = container.Resolve<ILogger>(); logger.Write(« »); Console.ReadKey(); } } }

, . ILgger.Write() , , habradigest 7 · 2009

Console.WriteLine(); Console.WriteLine(String.Format(" {0} », sw.ElapsedMilliseconds)); return result; }

24

.ET

#endregion } }

ILgger.Write() , ?

:

using System; using Microsoft.Practices.Unity; using Microsoft.Practices.Unity.InterceptionExtension; namespace UnityInAction1 { class Program { static void Main(string[] args) { IUnityContainer container = new UnityContainer(); container.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager()); container.AddNewExtension<Interception>(); container.Configure<Interception>() .SetInterceptorFor<ILogger>(new TransparentProxyInterceptor()); var logger = container.Resolve<ILogger>(); logger.Write(« »); Console.ReadKey(); } } }

David Hayde. . , , , - "Applyig Dmai-Drive Desig ad atters" by Jimmy ilss. .

.

habradigest 7 · 2009

25

.ET

Microsoft Object Builder

acerv

Java- Spring Tapestry, «» Microsoft ­ Composite UI Application Block (CAB) Unity. , . Java- , .Net- IoC. , ­ ( ) CAB ­ Microsoft Object Builder.

Object Builder ( OB) ­ . OB Micrsft 2005 « » atters ad ractices ­ CAB ( SmartCliet). CAB OB ( , , , ..).

. . , , , , Microsoft OB () ­ .

CAB . GAC , OB.

Object Builder

, OB . .

--Builder ­ , . (BuildUp), (TearDown). Builder (Strategy), . , Builder ­ .. (Policy) . , BuildUp . . --Strategy ­ , OB. - . , Builder ­ . . --Policy ­ . - . (.. )

habradigest 7 · 2009

-- Locator LifeTimeContainer ­ , , , OB . Locator ­ , LifeTimeContainer Builder WeakReferece. , LifeTimeContainer (.. , , ). -- Stage ­ OB . : · (reCreati) · (Creati) · (Iitializati) · - (stIitializati) · OB - .

! , ­ IProgramService:

interface IProgramService { void DoWork(); }

:

class ProgramService : IProgramService { #region IProgramService Members public void DoWork() { Console.WriteLine(string.Format("[{0}] Program Service: DoWork()", _guid)); } #endregion private Guid _guid = Guid.NewGuid(); public Guid Guid {

26

.ET

get { return _guid; } } }

ITypeMappiglicy. :

class TypeMappingPolicy : ITypeMappingPolicy { #region ITypeMappingPolicy Members public DependencyResolutionLocatorKey Map(DependencyR esolutionLocatorKey incomingTypeIDPair) { return new DependencyResolutionLocatorKey(typeof(Pr ogramService), null); } #endregion }

:

Builder builder = new Builder(); Locator locator = new Locator(); IProgramService service = builder.BuildUp<ProgramServic e>(locator, null, null); service.DoWork();

. .

, , :

public Builder(IBuilderConfigurator<BuilderStage> configurator) { Strategies.AddNew<TypeMappingStrategy>(BuilderStage. PreCreation); Strategies.AddNew<SingletonStrategy>(BuilderStage. PreCreation); Strategies.AddNew<ConstructorReflectionStrategy>(Build erStage.PreCreation); Strategies.AddNew<PropertyReflectionStrategy>(BuilderS tage.PreCreation); Strategies.AddNew<MethodReflectionStrategy>(BuilderSta ge.PreCreation); Strategies.AddNew<CreationStrategy>(BuilderStage. Creation); Strategies.AddNew<PropertySetterStrategy>(BuilderSta ge.Initialization); Strategies.AddNew<MethodExecutionStrategy>(BuilderSta ge.Initialization); Strategies.AddNew<BuilderAwareStrategy>(BuilderStage. PostInitialization); Policies.SetDefault<ICreationPolicy>(new DefaultCreationPolicy()); if (configurator != null) configurator.ApplyConfiguration(this); }

:

builder.Policies.Set<ITypeMappingPolicy>(new TypeMappingPolicy(), typeof(IProgramService), null); IProgramService service = builder.BuildUp<IProgramServi ce>(locator, null, null);

SingletonStrategy (reCreati) ­ . , . . , ..

DependencyResolutionLocatorKey: IProgramService service = builder.BuildUp<ProgramServic e>(locator, null, null); DependencyResolutionLocatorKey key = new DependencyReso lutionLocatorKey(typeof(ProgramService), null); locator.Add(key, service); IProgramService service2 = builder.BuildUp<ProgramServi ce>(locator, null, null);

service service2 . ConstructorReflectionStrategy (PreCreation) ­ . ­ , [IjectiCstructr] [Depedecy] . , .

[InjectionConstructor] public ServiceConsumer([Dependency]IProgramService service) { _service = service; }

, . TypeMappingStrategy (PreCreation) ­ . , , . , , IrgramService? , IrgramService, , ­ ? habradigest 7 · 2009

27

.ET

. Depedecy , , . , (Createew), :

[InjectionConstructor] public ServiceConsumer( [Dependency(CreateType=typeof(ProgramService), NotPre sentBehavior=NotPresentBehavior.Throw)]IProgramService service) { _service = service; }

[Dependency(CreateType=typeof(ProgramService), NotPresentBehavior=NotPresentBehavior.CreateNew)] public IProgramService ProgramService { set { _service = value; } get { return _service; } }

:

[CreateNew] public ProgramService ProgramService2 { set { _service = value; } }

, , , :

IProgramService service = builder.BuildUp<ProgramServic e>(locator, null, null); DependencyResolutionLocatorKey key = new DependencyReso lutionLocatorKey(typeof(IProgramService), null); locator.Add(key, service); ServiceConsumer consumer = builder.BuildUp<ServiceConsu mer>(locator, null, null);

MethodReflectionStrategy + MethodExecutionStrategy (Initialization). , rperty-. , , , [IjectiMetd].

[InjectionMethod] public void DoWork([Dependency]IProgramService service) { service.DoWork(); }

CreationStrategy (reation) ­ . . ­ ICreatilicy, , , «». ( ) () . Activatr. , . :) , Stage Creati. , -- ew(), . , . PropertyReflectionStrategy + PropertySetterStrategy (Initialization). ( , , ), . , ­ rpertyReflectiStrategy , [Depedecy], , , IrpertySetterlicy, . , , rpertySetterStrategy, , , , . , IrpertySetterlicy. habradigest 7 · 2009

BuilderAwareStrategy (PostInitialization). OB IBuilderAware, ­ OBuiltUp, OTearigDw. , ( ) , . , ( ).

#region IBuilderAware Members public void OnBuiltUp(string id) { Console.WriteLine("Built Up!"); } public void OnTearingDown() { Console.WriteLine("Tearing down!"); } #endregion

«» OB. , . , OB -- , , , .. , , , .

,

­ . 28

.ET

, , OB ­ , . OB . CAB ­ OB, . : , , ­ OB . ( !), BuildUp, , . ­ , . : , . -, ( ) .

Object Builder .

OB . , , , , , . , Micrsft Object Builder 2, , Micrsft Object Builder. Micrsft CAB ­ Uity. Uity Applicati Blck ­ WF. , , CAB Uity. , , : CAB: msd.micrsft.cm/e-us/library/aa480450.aspx CAB: www.cdeplex.cm/smartcliet Uity: msd.micrsft.cm/e-us/library/cc468366.aspx Uity: www.cdeplex.cm/uity CAB Uity: www.cdeplex.cm/ CmpsiteWF/Release/rjectReleases. aspx?ReleaseId=16941

habradigest 7 · 2009

29

.ET

Use Case Driven Development Composite UI Application Block

acerv

- Microsoft .NET -- Composite UI Application Block. Java, , Java Spring. use case driven -- .

, frt-ed - WiFrms .ET 2.0. , -- . , , , -- -, , -, , . , , , . .

, ( ).

- , , - - lse-cuplig ( ). Cmpsite UI Aplicati Blck ( CAB).

Use Case Driven Development

: (. Use Case, : , ) -- ( ), , , (. Actrs).

Composite UI Application Block

-- ( ), . , , - ( ). , -- CAB -, , - - view-. . -- . use case drive :) (, -- , , UML) , CAB : -- . -- Evet Brker Cmmad, lsecuplig -- Mdel-View-reseter ( MVC) view- -- , , -- , , - ( , ) ..

-. . ( ) , , , . , -- - - . , Micrsft -- UserCtrl -, . .., , Visual Studi -- , . Mkey-style, , , , . , , , habradigest 7 · 2009

30

.ET

CAB , .ET WiFrms, . , . WorkItem () -- . -- , -, , , , , , ( ). - . RtWrkItem, aret ( ) (sub-use cases). RootWorkItem ( ) -- - . - -- -. Service (, ). , public . - (, , ), view . Module () -- , .. uit f deplymet. , . , (-), , . -- .ET. ProfileCatalog -- . . , -- , -, -- . xml-, IMduleEumeratr -- , -. ModuleLoader -- . , , , . , , . ModuleInit -- (). view-lgic. , MduleLader .ET .

Shell Application -- . RtWrkItem. , view-lgic (-, ) Shell -- -. . . - ( ). Workspace -- . view- ( Smartart-). -- IWrkspace. CAB -- :) UIExtensionSite -- . , , -- , , .. RtWrkItem , -- , , . , , CAB -- . Command -- «». WrkItem-. . , , , , [CmmadHadler]. EventPublication EventSubscription -- . «» Evet Brker. , , . , , «» . , - , (lse-cuplig). , . Model -- . , MVC :) , (, , , , ..). View -- . - , .. , UI- ( , , listbx ..) Presenter -- . Ctrller MVC. . - (), . . View. , 31

habradigest 7 · 2009

.ET

, . SmartPart -- Mdel-View-reseter. «» . ( ). Microsoft Object Builder -- . , . , , .

InitializeComponent(); } [CreateNew] public FileSaveDialogPresenter Presenter { get { return _presenter; } set { _presenter = value; _presenter.View = this; } } private FileSaveDialogPresenter _presenter; } public class FileSaveDialogPresenter : Presenter<IFileSaveDialog> { [InjectionConstructor] public FileSaveDialogPresenter( [ServiceDependency]IFileSaver fileSaver, [ServiceDependency]IContentReader contentReader) { _fileSaver = fileSaver; _contentReader = contentReader; } protected override void OnViewSet() { base.OnViewSet(); View.OkClicked += SaveFile; } public void SaveFile(object o, EventArgs e) { _fileSaver.SaveFile(_contentReader.GetContent(), View.GetFileName()); } }

, . , , , -, , -, . , . - CAB. , , Micrsft Wrd2, -... , , -, ( ). -- , :

public interface IFileSaver { void SaveFile(byte[] content, string fileName); } public interface IContentReader { byte[] GetContent(); }

:

public class FileSaveWorkItem : WorkItem { protected override void InitializeServices() { base.InitializeServices(); Services.AddNew<FileSaver, IFileSaver>(); } protected override void OnInitialized() { base.OnInitialized(); Commands.AddNew<Command>(CommandNames.SaveFile); CommandBarButton invoker = Commands[CommandNames. SaveFile].AddInvoker(new CommandBarButton(" »), "ItemClick"); UIExtensionSites[SiteNames.MainToolbar]. Add<CommandBarButton>(invoker); } [CommandHandler(CommandNames.SaveFile)] public void HandleSave(object a, object b) { object smartPart = SmartParts.

IFileSaver , ICtetReader - ( , ). Smartart . , MV ( , , , ):

public interface IFileSaveDialog { event EventHandler OkClicked; string GetFileName(); } [SmartPart] public class FileSaveDialog : UserControl { public FileSaveDialog() {

habradigest 7 · 2009

32

.ET

AddNew<FileSaveDialog>(); Workspaces[WorkspaceNames.ModalWorkspace]. Show(smartPart); } }

: . :

WorkItems.AddNew<FileSaveWorkItem>().Run();

, . -- . - , (, ) . Ok, . , (, , -- Object Builder). . , . :)

-- , , . - , .., CAB -- , . , , , . , . , , -- , , , CAB . , , .. . - - , .

CAB .

, . , , ? , , « ». , - CAB-.

CAB -- , , . -

habradigest 7 · 2009

33

-

Skaizer,

, 75% 65% . - -- , . WCAG - , , , , , . , , -, , , , .

: -- 2 . ; -- 9 . ; -- 3.4 . ; -- 1.5 . ; -- 6 . . : -- 10 . ; -- 28 . ; -- 8 . ; -- 6.8 . ; -- 25 . . -- , , .

, . , , .

, , , « » . , , .

--

, JAWS Windows-Eyes, -. , , - . , , , -- , , . , , . , . , , .

.

habradigest 7 · 2009

34

« »

, , « », -, , . , , , , .

. , . , - «» , alt=» ». , , , « , » . , , : alt=«». .

,

, JAWS, - « ». -- « » «», , .

, <1> <6>. , . , , -. <1> , .

, , . , , , , , « , » -- , , . -

. , « , Ag IT» : « Ag IT». « » , , .

- -- . -- , -- <title>. , , -. , « ». , .

, , , . .

,

, -- -. , , 35

, habradigest 7 · 2009

- , .

--

, -. , , , Superva ZmText. , .

, WCAG. , , .

. , , , . , , , . , , -, .

.

, , HTML. . , , , . , , .

.

. , .

, , . HTML, Micrsft Wrd Adbe DF, .

,

, , -, .

, , , , . -, , Drag aturally Speakig. , -- . , , .

, . , - , - , .

, , , , . , Juicy Studi clr ctrast aalyzer. habradigest 7 · 2009

.,

36

, - . , , cage, , ( , cage , , , ).

. , .

, , , -, . , -. , , . , «», «» , «», .

focus

, :fcus . , , - - , . CSS , , :

a:hover, a:focus, a:active {color: #000000;}

, , . , (. - , , , -- , . :

:

-- , . , , , , , , .

, , . , ; , , , .

-. , . , . , . , .

. , , . , habradigest 7 · 2009

37

, . , .

, , . , . - . .

, , . , , .

, Brwse Alud Textic - . , .

.

, , -, . , , , - , , , .

habradigest 7 · 2009

38

YTHO

--

Skaizer

« ». Python. ? SEO-, ... , . . , .. ( , ). « » ( ).

, . . , , , . , , . , .

, . , , . . , , , , . , , , .

?

, . .

?

, 2 , . : -- ; -- ; -- ; -- . . . CRC32, , SHA1 MD5 .. , . , : -- : «My war is ver.» : 1759088479 -- : «My war is ver!» : -127495474 : «My war is ver». -, 39

. , 8 . , . 7 8 . , . 5-6 , - . , , . , -, , . . , habradigest 7 · 2009

YTHO

, , , , . , , .. ( , .., ). , : , , « ». , , , .. , . - . , , 2 : surce1 surce2. . - -.

stop_symbols = '.,!?:;-\n\r()' stop_words = (u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'')

caize - -, , . , , . , , , .., ( , ). , . -- . 10 . . , , .., : « , , , , .»© . . : . 10 . , le(surce)-(sigleLe-1), .. 1. : -- S1 = -- S2 = -- S3 = -- S4 = , :

def genshingle(source): shingleLen = 10 # out = [] for i in range(len(source)-(shingleLen-1)): out.append (' '.join( [x for x in source[i:i+shingleLen]] ).encode('utf-8')) return out

- , . - , , . , :

def canonize(source): stop_symbols = '.,!?:;-\n\r()' stop_words = (u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'') return ( [x for x in [y.strip(stop_symbols) for y in source.lower().split()] if x and (x not in stop_words)] )

40

habradigest 7 · 2009

YTHO

, . CRC32, biascii, . :

def genshingle(source): import binascii shingleLen = 10 # out = [] for i in range(len(source)-(shingleLen-1)): out.append (binascii.crc32(' '.join( [x for x in source[i:i+shingleLen]] ).encode('utf-8'))) return out

shingleLen = 10 # out = [] for i in range(len(source)-(shingleLen-1)): out.append (binascii.crc32(' '.join( [x for x in source[i:i+shingleLen]] ).encode('utf-8'))) return out def compaire (source1,source2): same = 0 for i in range(len(source1)): if source1[i] in source2: same = same + 1 return same*2/float(len(source1) + len(source2))*100 def main(): text1 = u'' # 1 text2 = u'' # 2 cmp1 = genshingle(canonize(text1)) cmp2 = genshingle(canonize(text2)) print compaire(cmp1,cmp2) # Start program main()

:

[1313803605, -1077944445, -2009290115, 1772759749]

, 2 2 2 , .

def compaire (source1,source2): same = 0 for i in range(len(source1)): if source1[i] in source2: same = same + 1 return same*2/float(len(source1) + len(source2))*100

, , . , , , . , , , , , 25, 10 40. , (!) , . « » -- « » « », .

, .

# -*- coding: UTF-8 -*if __name__ == '__build__': raise Exception def canonize(source): stop_symbols = '.,!?:;-\n\r()' stop_words = (u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'', u'') return ( [x for x in [y.strip(stop_symbols) for y in source.lower().split()] if x and (x not in stop_ words)] ) def genshingle(source): import binascii

habradigest 7 · 2009

41

YTHO

, .. Python

kmike

-- - ? , , , -- , ? . -- mystem, lemmatizer phpmorphy Python, . , Python, MIT.

-- ?

-, yt. - . mystem - , lemmatizer ppmrpy , pyt - . , , , , . , , . at.ru. (LGL) , -- . , . ( ), , . -- , , . , , , : 1. (, .., .. ) -- «» «» 2. ( ). , «» - , , , .

, , . : []+[]+[]+[] -- «», «» .. . -- , , («»,«»). , «» «», .. «». -- , , - . « -- », + «» ( ). . , - , . , , . -- . ( , )) -- . , ( ). . -- («» , . ). «» , .. 2 , , . -- , , , , . 42

at.ru : 1. ; 2. ; 3. ; 4. ( ); 5. ( , ); 6. -- . habradigest 7 · 2009

YTHO

, .

, , <>+<>+<>+<> <>+<>+<> , ( ), «» ( ) 2. -- 20 . <>+<>+<>, , . -: , () (), . , <>+<>, . , , *. , , . lemmas: {base -> [rule_id]}, .. -- , -- . -- , -- , , 2 .. . , , , . -- . * -- <>+<>, - 5 , , , , .

. ( , ), «», «» . , , , . , , «#», . , , .

«», , . , , . 2 , : 1. , - , , , 2. 2 , , , . -- . : , 2 .. , , . . ( ) (- , )) «» . , , . « » ( 5 ). , . -- , -- . -- , , 1, 2, 3, 4, 5- , . -- . , , , , . . , . , , .. .., TODO. -- , « », 43

-- , , , 90% )

, , «» -- «», , , . -- habradigest 7 · 2009

YTHO

, : . : -- , ! ! . . : -- , ! - ! . , . : -- . - . . : -- ! ! ! ! , «»( «» «»), «», «-», «» «», , , . , . , «» . «» -- , «». , , , . ,

, . , . (aydbm selve). , DbfileameSelf - . , , - Self, DbfileameSelf. (995 , , macbk):

get_pickle_morph('ru', predict_by_prefix = False): 0.214 CPU seconds get_pickle_morph('ru'): 0.262 CPU seconds get_shelve_morph('ru', predict_by_prefix = False): 0.726 CPU seconds get_shelve_morph('ru'): 0.874 CPU seconds

selve, , . selve , , . 20 . , : , DbfileameSelf, 5 , . . , , , - , . -. .

3:

. , , 10 , . -- . 2 ( ) «», , ( pickle/cickle). 1. 3-4 2. 150 psyc 100 ( + , set list tulpe, ). , . yt duck typig. -- . , «» , , , , -- [] i. ) «» . (bsddb, dbm, gdbm), habradigest 7 · 2009

import pymorphy morph = pymorphy.get_shelve_morph('ru') # info = morph.get_graminfo(unicode('').upper())

-, ?

, . , . , , . , , , . , . -- , , .

pymrpy.py -- ; selve_adds.py -- self, ; 44

YTHO

ecde_dicts.py -- , AOT pymrpy. , , 200 , 1 . - ; test.py -- - pymrpy; example.py -- 995 ; dicts/src -- , at.ru; dicts/cverted -- , ecde_dicts.py .

: www.assembla.cm/wiki/sw/pymrpy g.assembla.cm/pymrpy trac-g.assembla.cm/pymrpy -- MIT. yt 2.5.

habradigest 7 · 2009

45

YTHO

:

uj2

, . ( ). , . , , - , Haskell.

, : -- (pattern matching) -- , -- (continuation) -- (.. «» ). yield -- -- , , , , -- , , -- .. .. , ) ( , ), ) «» «» . .

<title>%s</title> </head> <body> <h1>Hello</h1> </body> «»» % params['title']) f.close() # PLAIN TEXT def text_writer(filename): f = open(filename + '.' + type, 'w'); f.write(«»» %s ================================= Hello «»») f.close() # , , if type == 'html': return html_writer elif type == 'txt': return text_writer params = { 'title': 'Header' } # HTML f = get_writer('html', params) f('file1') # PLAIN TEXT f = get_writer('txt', params) f('file2')

, (first-class object). , ( ), , , . (clsure) -- .. ( , ). ( ):

# encoding: utf-8 def get_writer(type, params): # HTML def html_writer(filename): f = open(filename + '.' + type, 'w'); f.write(«»» <html> <head>

, tml_writer text_writer get_writer (type params). ? get_writer , , ? : , -- (, , ) . , ( ), -- + .

. 46

habradigest 7 · 2009

YTHO

. :

# encoding: utf-8 import math # y = k * x + b def get_linear(k, b): return lambda x: k * x + b # y = k * x^2 + b def get_sqr(k, b): return lambda x: k * x ** 2 + b # y = A * sin(k * x + phi) def get_sin(amplitude, phi, k): return lambda x: amplitude * math.sin(math.radians(k * x + phi)) # y = A * e^(k*x) def get_exp(amplitude, k, b): return lambda x: amplitude * math.exp(k * x + b)

def sqr(x): return x ** 2

. , . ? , «» , . idetity -- -- . , -- . . , , -- . , , :

y = x_scaler(shifter(x_scaler(sqr, 5), 6), 7)

. :

# y = 5 * sin(0.3 * x + 30) y = get_sin(5, 30, 0.3) # y(90) = 4.19 print y(90) print # y 0 180 print [ y(x) for x in range(0, 180) ]

? ... , x_scaler(5) sqr, x_scaler. sifter. x_scaler. sqr. , «». : . :

def y(x): return sqr(((x * 7) + 6) * 5)

, , X. ! X Y:

def shifter(func, b): return lambda x: func(x + b) def x_scaler(func, k): return lambda x: func(k*x) def y_scaler(func, A): return lambda x: A * func(x) def combine(func1, func2): return lambda x: func2(func1(x))

, . y = 5 * si(0.3 * x + 30):

# y # y # y # y y_scaler(5) = y_scaler(math.sin, 5) -- = combine(math.radians, y) -- shifter(30) = shifter(y, 30) -- x_scaler(0.3) = x_scaler(y, 0.3)

, .

, , , :

def modulate(mod, src): return lambda x: mod(x) * src(x)

sifter, x_scaler, y_scaler, cmbie -- (ig-rder fuctis), .. , , . Cmbie -- , . :

def identity(x): return x

:

# y1 = 5 * sin(15 * x + 30) --

habradigest 7 · 2009

47

YTHO

y1 = \ x_scaler( shifter( combine( math.radians, y_scaler( math.sin, 5)), 30), 15) # y2 = exp(-0.01 * x) -- y2 = x_scaler(math.exp, -0.01) y = modulate(y2, y1) print [ y(x) for x in range(0, 180) ]

Lisp... , :) -, Lisp -- . -- , , -- . -- , defu, , , . . , -- Lisp ( ). ... , . Lisp -- , ( eval , ). Lisp , . ( fr? , fr Cmm Lisp -- , , fr ). , ( CLOS -- , ). . , , -- :) Lisp , -- ? (, ) yt. , , , , , . -- fr, wile, d... wile. , . .. , . , . Lisp ( -- , , ..): -- (map) -- , :

-, :

, , . , map-reduce list cmpreesis . : 1 2 3 4 . . , . ? Lisp. ( ) . . , -- , ( ) -- . + -- , . -- , , .. -- .

habradigest 7 · 2009

48

YTHO

-- (filter) -- -, , :

a. LC -- , . LC map :

map(lambda a: expression(a), x)

, if:

[ expression(a) for a in x if condition(a) ]

-- (reduce) -- . : ; -; -- , . . , . - (, , ). :

, filter. :

map(lambda a: expression(a), filter(lambda a: condition(a), x))

reduce , .. , LC -- . : map . : , -- ..:

map( lambda [1, 2, [4, 5, [7, 8, a1, a2, a3: a1 + a2 + a3, 3], 6], 9])

LC , , : , . . , . , . . , , , - , . yt , list cmpreesi ( , - ).

[ expression(a1, a2) for a1 in x1, for a2 in x2 ]

, , . . :

[ a1 + a2 for a1 in [ 'a', 'b', 'c'] for a2 in ['x', 'y'] ] => ['ax', 'ay', 'bx', 'by', 'cx', 'cy']

, LC , , 1 10. (. ) .

List comprehensions (LC)

LC :

[ expression(a) for a in x ]

. :

x = [ 2, 3, 4, 5, 7, 5 ]

x -- , a -- , expressi(a) -- , habradigest 7 · 2009

- ; , : 49

YTHO

map(lambda a: a ** 2, x) # , LC [ a ** 2 for a in x ] => [4, 9, 16, 25, 49, 25]

. , reduce e. :

-- :

filter(lambda a: a % 2 == 1, x) # , LC [ a for a in x if a % 2 == 1 ] => [3, 5, 7, 5]

-- :

filter(lambda a: a map(lambda a: a x)) # , [ a ** 2 for a in % 2 == 1, ** 2, LC x if a ** 2 % 2 == 1 ]

=> [9, 25, 49, 25]

, , -- . reduce. :

reduce(lambda a, b: a + b, x, 0) => 26

, . , 2, 3, 4, 5, 7, 5. : 5, 7, 5, 4, 3, 2. , , -: (5, (7, (5, (4, (3, (2)). , . : (5, (7, (5, (4, (3, (2, [])). :

reduce(lambda a, b: [ b ] + a, x, []) => [5, 7, 5, 4, 3, 2]

, , ( , ). -- , -- , . , , :

reduce(lambda a, b: a * b, x, 0) => 0

, :

0. : , : ((((((0 * 2) * 3) * 4) * 5) * 7) * 5). , :

reduce(lambda a, b: a * b, x, 1) => 4200

. :

reduce(lambda a, b: max(a, b), x) => 7

, «» , , , , , , , . , - . , . 50

habradigest 7 · 2009

WEB-

IE. hasLayout

Panya

IE . , - , , . IE -- hasLayout.

hasLayout?

IE , , . . , - , , , «layut». asLayut IE, «layut» .. , , , , . HTML , «layut» (asLayut = true): <tml>, <bdy>, <table>, <tr>, <td>, <t>, <img>, <iput>, <butt>, <textarea>, <select>, <fieldset>, <leged>, <r>, <iframe>, <embed>, <bject>, <applet>, <marquee>. asLayut IE , css . «layut» (asLayut = true): -- psiti: abslute -- flat: left rigt -- eigt, widt: aut -- display: ilie-blck -- zm: rmal ( ) -- writig-mde: tb-rl -- verflw, verflw-x, verflw-y: aut|scrll|idde ( IE7) -- psiti: fixed ( IE7) -- mi-widt, mi-eigt: ( IE7) -- max-widt, max-eigt: e ( IE7) asLayut (: widt: aut flat: e). , asLayut habradigest 7 · 2009

O avig layut -- te ccept f asLayut i IE/Wi ().

hasLayout

asLayut IE. , , asLayut. asLayut. . , , -, . , , ( eigt aut) asLayut ( true). - , , asLayut «layut» , asLayut . asLayut DOM Iteret Explrer Develper Tlbar. , IE , :

, View IE6 (View Explrer Bar IE Develper Tlbar) Tls IE7 (Tls Tlbars Explrer Bar 51

WEB-

IE Develper Tlbar). , asLayut, ( Firebug «Ispect»). «Curret Style» , . asLayut «layut». -1 (true), asLayut , «layut». , asLayut . - . , , flat: left; , ( asLayut), ( ). , , asLayut. -, , , . , eigt 1% display: ilie-blck, . eigt: 1%, , , , . , zm 1 ( 100%). , , IE, Cditial Cmmets. , IE < 6 , display: ilie-blck eigt: 1%. , asLayut : 1. IE. 2. HTML . 3. CSS, . 4. - asLayut . 5. zm: 1; , asLayut, HTML , , CSS IE. , , habradigest 7 · 2009

asLayut :)

: hasLayout

, . , . :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict// EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict. dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru"> <head> <title> 1. position:absolute.</title> <meta http-equiv="Content-Type" content="text/ html;charset=utf-8"/> <style type="text/css"> * { margin:0; padding:0; } .zoom { zoom:1; } div.parent { position:relative; border:1px solid #000; padding:20px; margin:10px; } div.parent div { position:absolute; width:20px; height:20px; top:0; left:0; background:#0c0; } div.parent div.bottom { top:auto; bottom:0; } </style> </head> <body> <div class="parent"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

52

WEB-

<div></div> <div class="bottom"></div> </div> </body> </html>

1 . , , . , IE6 :

background:#0cc; } </style> </head> <body> <div class="parent"> <ul> <li></li> <li></li> <li></li> </ul> </div> </body> </html>

2 , , . IE 6 7 ( - , ):

«layut» (div.paret) «zm». : 1 ( ) . :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict// EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict. dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru"> <head> <title> 2. </title> <meta http-equiv="Content-Type" content="text/ html;charset=utf-8"/> <style type="text/css"> * { margin:0; padding:0; } .zoom { zoom:1; } div.parent { border:1px solid #000; padding:20px; margin:10px; } div.parent ul { background:#00c; } div.parent ul li { border:1px solid #000;

, asLayut (div.paret) : 2 ( ) . :

<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Strict// EN» «http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict. dtd»> <html xmlns=»http://www.w3.org/1999/xhtml» xml:lang=»ru»> <head> <title> 3. </title> <meta http-equiv="Content-Type" content="text/ html;charset=utf-8"/> <style type="text/css"> * { margin:0; padding:0; } .zoom { zoom:1; } div.parent { border:2px solid #000; margin:10px 20%; } div.parent div.float {

habradigest 7 · 2009

53

WEB-

background:#cc0; float:left; margin:2px; text-align:center; width:50px; height:50px; line-height:50px; } </style> </head> <body> <div class="parent"> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div class="float">Float</div> <div style="clear:both;"></div> </div> </body> </html>

zm : 3 ( ) , asLayut : -- ( 4). -- ( 5). -- asLayut ( 6). -- display:ilie-blck . ( 7).

hasLayout

, asLayut . , , «» . asLayut, , , , asLayut . , , asLayut .

3 IE :

habradigest 7 · 2009

54

WEB-

memcached/MemcacheDB

smira

memcached MemcacheDB. , , , , , .. memcached get/set. memcached .

Memcaced MemcaceDB , , "memcaced". memcaced? , .. , MemcaceDB, . ( ), , , . , , memcaced, ( ) memcaced. 6 : -- ; -- ; -- ; -- ; -- ; -- . C , -- . yt, memcaced:

class Memcache(object): def get(self, key): """ . @param key: @type key: C{str} @return: @raises KeyError: """ def add(self, key, value, expire=0): """ , . @param key: @type key: C{str} @param value: @param expire: " " (0 -- ) @type expire: C{int} @raises KeyError: """ def incr(self, key, value=1): """ . @param key: @type key: C{str} @param value: @type value: C{int} @return: ( ) @rtype: C{int} @raises KeyError: """ def append(self, key, value): """ . @param key: @type key: C{str} @param value: @raises KeyError: """ def delete(self, key): """ .

habradigest 7 · 2009

55

WEB-

@param key: @type key: C{str} """

:

class MemcacheObject(object): def __init__(self, mc): """ . @param mc: memcached @type mc: L{Memcache} """ self.mc = mc

""" assert not self.locked try: self.mc.add(self.key, 1, self.timeout) except KeyError: return False self.locked = True return True def unlock(self): """ . """ assert self.locked self.mc.delete(self.key) self.locked = False

.

(mutex, spilck) -- , "" memcaced. , AI memcaced, . , , ( , memcaced), "" ( , , , , , ). : -- (try-lck); -- (ulck).

`add`, "" , . , , wit- yt. .

.

, , . "" "" . : . : . : -- ; -- .

class MCLock(MemcacheObject): def __init__(self, mc, name, timeout=5): """ . @param name: @type name: C{str} @param timeout: () @type timeout: C{int} """ super(MCLock, self).__init__(mc) self.key = 'lock_' + name self.locked = False self.timeout = timeout def try_lock(self): """ . @return: ? @rtype: C{bool}

class MCCounter(MemcacheObject): def __init__(self, mc, name): """ . @param name: @type name: C{str} """ super(MCCounter, self).__init__(mc) self.key = 'counter' + name def increment(self, value=1): """ . @param value:

habradigest 7 · 2009

56

WEB-

@type value: C{int} """ while True: try: self.mc.incr(self.key, value) return except KeyError: pass try: self.mc.add(self.key, value, 0) return except KeyError: pass def value(self): """ . @return: @rtype: C{int} """ try: return self.mc.get(self.key) except KeyError: return 0

.

T. , T 5 . , -- T ( T). : -- ( T ); -- .

def time(): """ (, UNIX Epoch). @return: @rtype: C{int} """ class MCVisitorCounter(MemcacheObject): def __init__(self, mc, name, T): """ . @param name: @type name: C{str} @param T: , @type T: C{int} """ super(MCVisitorCounter, self).__init__(mc) self.keys = ('counter' + name + '_0', 'counter' + name + '_1') def _active(self): """ . @return: 0 1 """ return 0 if (time() % (2*T)) < T else 1 def increment(self): """ . """ active = self._active() while True: try: self.mc.incr(self.keys[1-active], 1) return except KeyError: pass try: self.mc.add(self.keys[1-active], 1,

, -- "" icremet. . icr , , , add, icr. , .. icr add : memcaced icr . , memcaced ? , : -- memcaced ; -- memcaced ( ""). ( MemcaceDB, .. .) memcaced -- , , ( , , memcaced). , , memcaced-.

habradigest 7 · 2009

57

WEB-

2*T)

# 43 return except KeyError: pass

def value(self): """ . @return: @rtype: C{int} """ try: return self.mc.get(self.keys[self._ active()]) except KeyError: return 0

_active() icremet() . icremet() , , , 1000 =3 . _active() , , . 2*T "" 0, T time() % (2*T). , memcaced ( ), 1,2,...,T-1 ( -- 0 ). , 25 31 10 , 35- ( 36-) 0 ( 31- ). 43 :

self.mc.add(self.keys[1-active], 1, 2*T -- time() % T)

memcaced . -- : (), ( , ). T . 2*T , -- T , ( ), , . , , memcaced, .. . , , . _ active(): , , , ( ) active, .. , _active() , . , habradigest 7 · 2009

T, 5% . ( ), memcaced.

.

-- , T . , , . : -- ( ); -- , Tmi Tmax ( , , ).

def time(): """ (, UNIX Epoch). @return: @rtype: C{int}

58

WEB-

""" class Event: """ , . """ def when(self): """ , (). """ def serialize(self): """ . @return: @rtype: C{str} """ @static def deserialize(serialized): """ . @param serialized: @type serialized: C{str} @return: @rtype: C{list(Event)} """ class MCEventLog(MemcacheObject): def __init__(self, mc, name, timeChunk=10, numChunks=10): """ . @param name: @type name: C{str} @param timeChunk: @type timeChunk: C{int} @param numChunks: @type numChunks: C{int} """ super(MCEventLog, self).__init__(mc) self.keyTemplate = 'messagelog' + name + '_%d'; self.timeChunk = timeChunk self.numChunks = numChunks def put(self, event): """ . @param event: @type event: L{Event} """ serialized = event.serialize() key = self.keyTemplate % (event.when() // self. timeChunk % self.numChunks)

while True: try: self.mc.append(key, serialized) return except KeyError: pass try: self.mc.add(key, serialized, self. timeChunk * (self.numChunks-1)) return except KeyError: pass def fetch(self, first=None, last=None): """ ( ). @param first: @type first: C{int} @param last: @type last: C{int} @return: @rtype: C{list(Event)} """ if last is None or last > time(): last = time() if first is None or last < first or (last-first) > self.timeChunk * (self. numChunks-1): first = time() -- self.timeChunk * (self. numChunks-1) firstKey = first / self.timeChunk % self. numChunks lastKey = last / self.timeChunk % self. numChunks if firstKey < lastKey: keyRange = range(firstKey, lastKey+1) else: keyRange = range(firstKey, self.numChunks) + range(0, lastKey+1) keys = [self.keyTemplate % n for n in keyRange] result = [] for key in keys: try: events = Event.deserialize(self. mc.get(key)) except KeyError: continue result.extend(filter(lambda e: e.when() >= first and e. when() <= last, l)) return result

habradigest 7 · 2009

59

WEB-

-- , umCuks memcaced. ( ) timeCuk , ( , ). , .. umCuks * timeCuk , -- (umCuks - 1) * timeCuk , timeCuk . , ( , ) (umCuks - 1) * timeCuk . , . timeCuk umCuks : , timeCuk, (, 10-20). , umCuks. Evet, -- , . put , evet, , "", evet.we() (umCuks - 1) * timeCuk ( ). put , , . , . fetc , , first last. , last , first -- , . , , [first, last]. : 1. evets = fetc(). habradigest 7 · 2009

lastSee max(evets.we()). 2. : evets = fetc(first=lastSee), lastSee .

. 1

, , . : -- ( ); -- ( ).

1

def serializeArray(array): """ . """ def deserializeArray(str): """ . """ class MCArray1(MemcacheObject): def __init__(self, mc, name): """ . @param name: @type name: C{str} """ super(MCArray1, self).__init__(mc) self.lock = MCLock(name) self.key = 'array' + name def fetch(self): """ . @return: @rtype: C{list} """ try: return deserializeArray(self.mc.get(self. key)) except KeyError: return [] def change(self, add_elems=[], delete_elems=[]): """ , . @param add_elems: , @type add_elems: C{list} @param delete_elems: ,

60

WEB-

@type delete_elems: C{list} """ while not self.lock.try_lock(): pass try: try: array = deserializeArray(self. mc.get(self.key)) except KeyError: array = [] array = filter(lambda e: e not in delete_ elems, array) + add_elems self.mc.set(self.key, serializeArray(array), 0) finally: self.lock.unlock()

""" def deserializeIntArray(str): """ . """ class MCArray2(MemcacheObject): def __init__(self, mc, name): """ . @param name: @type name: C{str} """ super(MCArray2, self).__init__(mc) self.key = `array' + name def fetch(self): """ . @return: @rtype: C{list} """ try: return deserializeIntArray(self. mc.get(self.key)) except KeyError: return [] def add(self, element): """ . @param element: , , @type element: C{int} """ element = serializeInt(element) while True: try: self.mc.append(self.key, element) except KeyError: return try: self.mc.add(self.key, element, 0) except KeyError: return

1

, . reader-writer, . fetc , , "" age memcaced, get set memcaced fetc age, fetc : . MCLck, . gets, cas add memcaced , cage.

2

, " ". . , . : -- ( ); -- .

2

, . "" memcaced, ( ). , ( 61

2

def serializeInt(int): """ (str).

habradigest 7 · 2009

WEB-

, , ). ( ) : -- , ; , ( ); -- , "" "", +1 +3 +4 -3 +5 [1, 4, 5]; , , ( apped).

@param key: @type key: C{str} @rtype: C{bool} """ try: self.mc.get(self.key + '_v_' + key) return True except KeyError: return False def fetch(self): """ . @return: @rtype: C{list(str)} """ try: return deserializeArray(self.mc.get(self. key + '_keys')) except KeyError: pass def add(self, key): """ . @param key: @type key: C{str} """ while not self.lock.try_lock(): pass try: try: array = deserializeArray(self. mc.get(self.key + '_keys')) except KeyError: array = [] if key not in array: array.append(key) self.mc.set(self.key + '_v_' + key, 1, 0) self.mc.set(self.key + '_keys', serializeArray(array), 0) finally: self.lock.unlock() def delete(self, key): """ . add(). """

.

. : -- ( ); -- , , -- . , . , .

def serializeArray(array): """ . """ def deserializeArray(str): """ . """ class MCTable(MemcacheObject): def __init__(self, mc, name): """ . @param name: @type name: C{str} """ super(MCTable, self).__init__(mc) self.lock = MCLock(name) self.key = 'table' + name def has(self, key): """ .

memcaced -, , : . , . 62

habradigest 7 · 2009

WEB-

" 1". , fetc add , .. . : memcaced. , , ( ). , , , , .

, "" "", : -- memcaced ( add/set ..); -- ; -- ; -- "" ; -- reader-writer. , memcaced, , multi-get . , . , yt. , , , - -- .

habradigest 7 · 2009

63

JAVASCRIT

JavaScript:

depp

, JavaScript, , «» , . : - , , . , ,

JavaScript

« JavaScript -- ». , :) , , , , . , «» « ». JavaScript -- ( , ), -. ( ), -- . , JavaScript 6 -- Udefied ( ), ull, Blea ( ), Strig (), umber () Object (). 5 , Object -- . , , Object «»: (Array), (Fucti), (RegExp) . , . , Strig, umber Blea «» Object: Strig, umber Blea . , 'Hell, wrld', , , Strig. , , , . .

. . :

test=function() {alert(`Hello!')} // {alert(`Hello!')} ( , , ) test test_link=test; //test_link test(); //Hello! test_link(); //Hello!

, , . , test, test - «» «» , «test_lik» -- . , -- , . , -- , (, ), (garbage cllecti), , . , :

test={prop: 'sometext'} // prop test_link=test; // alert(test.prop); //sometext alert(test_link.prop); //sometext // test_link.prop='newtext'; alert(test.prop); //newtext alert(test_link.prop); //newtext /* , - .

-- habradigest 7 · 2009

64

JAVASCRIT

- . , , . */ // test.new_prop='hello'; delete test.prop; alert(test_link.prop); //undefined - alert(test_link.new_prop); //hello - // delete test; alert(test.new_prop); /* , test , test.new_prop */ alert(test_link.new_prop); //hello /* , , . test_link */ // test=test_link; // test test_link={prop: 'sometext'} // alert(test_link.prop); //sometext alert(test.prop); //undefined /* C , test test_link . , test_link , */ alert(test.new_prop); //hello - test

alert(obj.length); //6 - String length, alert(simple.length); //6 /* simple - , , String. */ obj.prop='text'; simple.prop='text'; alert(obj.prop); //text - obj , alert(simple.prop); //undefined - simple ,

umber, Blea (, , legt, ). , .. , . , . -- , , «test=ew Array()» «test=[]», . .

, , , , . , :

test={ simple_property: `Hello', object_property: { user_1: `', user_2: `' }, function_property: function(user) { alert(this.simple_property + `, ` + this.object_ property[user]); } } test.function_property(`user_1'); //Hello, .

, . , , -- -- . , , , .

, Strig umber , .

obj=new String('hello'); // simple='hello'; // alert(obj); //hello alert(simple); //hello -

test, 3 , , , . fucti_prperty, . . tis, (.. ) , . , tis.simple_prperty=test.simple_ prperty='Hell', tis.bject_prperty[user]=test. 65

habradigest 7 · 2009

JAVASCRIT

bject_prperty[user]=''. , tis , , , . , .

test.function_property(`user_1'); //Hello, . test2=new Object(); // , test2={} test.function_property.call(test2, 'user_1'); // /* call . , function_property test, this test, test2. .. object_property, this.object_property[user] */ // test2.simple_property='Good day'; test2.object_property=test.object_property; // , test.function_property.call(test2, 'user_1'); //Good day, .

make_me, this . name, _name, show_name. ( , ) child , */ alert(child.name); // child.show_name(); // child2=new make_me(''); child2.show_name(); // child2.show_name=function() {alert(' ');} // , child2.show_name(); // child.show_name(); // -

-- , , . , , Object (Function, Array ) -- , , .. , . . , . -, , . -, , , . .

, . -- , . «» .

2 , . simple_prperty bject_prperty. , . , . . JavaScript -- ( ), . .

make_me=function(_name) { alert(' '); this.name=_name; this.show_name=function() {alert(this.name);} } child=new make_me(''); // /* , . new , . .. make_me - , , -

( ), JavaScript. , , , -- . , :

make_me=function(_name) { alert(' '); this.name=_name; this.show_name=function() {alert(this.name);} } /* function, , .. - , -

habradigest 7 · 2009

66

JAVASCRIT

. , ( ) prototype, . , make_me.prototype=new Object(); , ( prototype) constructor, . . , {constructor: ... ...} - . */ alert(typeof make_me.prototype); //Object - , alert(typeof make_me.prototype.constructor); //Function - alert(make_me.prototype.constructor === make_me); // true make_me.prototype.set_name=function(_name) {this.name=_ name;} // make_me child=new make_me(''); // /* , , child [[Prototype]], , make_me.prototype. .. , , - */ alert(child.name); // child.show_name(); // child.set_name(''); /* , set_name child. , child.[[Prototype]], . */ child.show_name(); // - :) make_me.prototype.show_name2=function() {alert(', ' + this.name;} //.. - , child2=new make_me(''); child2.show_name2(); //, child.show_name2(); //, - , child2.show_name2=function() {alert(' ');} // , show_name2 ( ) «» child2.show_name2(); // - .. show_name2, ,

child.show_name2(); //, - make_me.prototype={prop: 'hello'} // alert(child.prop); //undefined child.show_name2(); //, /* , , . , [[Prototype]] child child2 ( make_me), make_me.prototype - , make_me */ child3=new make_me(''); alert(child3.prop); //hello -

, (.. ), . , ( ) -- . . , , :

make_me=function(_name) { alert(' '); this.name=_name; this.show_name=function() {alert(this.name);} } make_me.prototype.set_name=function(_name) {this.name=_ name;} child=new make_me(''); alert(typeof make_me.prototype); //object - prototype alert(typeof child.prototype); //undefined - prototype alert(child.constructor.prototype === make_ me.prototype); //true - constructor, - make_me, , , prototype

, , prttype [[rttype]] , . ( , ), , , , . , 67

habradigest 7 · 2009

JAVASCRIT

-- prttype, -- [[rttype]].

, , -- . . , .. -- , , . .

bird=function() {} // bird.prototype.cry=function(){alert('!');} // bird.prototype.fly=function(){alert(' !');} // duck=function() {} duck.prototype=new bird(); duck.prototype.cry=function(){alert('-!');} // duck.prototype.constructor=duck; // prototype.constructor duck, .. bird billy = new duck(); // - billy.fly(); // ! - , billy.cry(); //-! - -,

-- , (!) Object (.. Fucti.prttype. [[rttype]].cstructr===Object), -- , , tStrig, asOwrperty ( -- Fucti.prttype. [[rttype]]['asOwrperty'] -- , -- , ). , Object. ? , . Object.prttype , . Object.prttype.[[rttype]]=ull; . -- Object Fucti. .. Object.[[rttype]]. cstructr===Fucti. -- Object Fucti, Fucti.prttype -- Object. . , . cild, make_me, -- make_me.prttype. , , cild cild.[[rttype]] ( make_me.prttype), cild.[[rttype]]. [[rttype]] ( Object.prttype), tStrig, .

.

, , , .

make_me=function() {} child=new make_me(); alert(child.toString()); // [object]

, -- , JavaScript. . , , . , , . -- .

// man=function() { this.live=function(){alert(' ');} // this.walk=function(){alert(' ');} // } // poet=function(){ this.kill=function(){alert(' ');} //

make_me, . , make_me.prttype, cstructr, make_me. . .. make_me -- , , .. . -- Fucti(), -- , call, apply .. -- . , make_me [[rttype]], Fucti.prttype. , Fucti habradigest 7 · 2009

68

JAVASCRIT

this.live=function(){alert(' ');} // } vladimir=new man(); // - vladimir.live(); // - vladimir.walk(); // - poet.call(vladimir); // poet vladimir vladimir.kill(); // vladimir.live(); // // man.call(vladimir); vladimir.live(); //

-- . IE -- . , ( ) , . , - , . , (.. ), . , . , . .S. , - , . , .. , , , , :)

? -, , . 2, . -, - . . -, , , , .

, JavaScript, .

, , , , -- , , , . , , , . , Iteret Explrer 6 7 . 1. -- . , . , , . , , , , .. . 2. -- Micrsft. , , -- ( ) , . habradigest 7 · 2009 69

JAVASCRIT

JavaScript

sunnybear, webo.in

Steve Souders - JavaScript-. , : . ? ? . Steve onload / onreadystatechange . , . : - .

:

, . , :

var modules = [ [0, 'item1', function(){ alert('item1 is loaded'); }], [1, 'item2', function(){ alert('item2 is loaded'); }], [1, 'item3', function(){ alert('item3 is loaded'); }] ];

var script = document.createElement('script'); script.type = 'text/javascript'; /* */ script.src = module[1] + '.js'; /* */ script.text = module[2]; /* */ script.title = i + 1; /* IE */ script.onreadystatechange = function() { if (this.readyState === 'loaded') { /* , */ load_by_parent(this.title); } }; /* */ script.onload = function (e) { /* ( Opera) */ if (/opera/i.test(navigator.userAgent)) { eval(e.target.innerHTML); } /* , */ load_by_parent(this.title); }; /* */ document.getElementsByTagName('head')[0]. appendChild(script); } /* */ load_by_parent();

. ( , ), . , . , :

/* */ function load_by_parent (i) { i = i || 0; var len = modules.length, module; /* */ while (len--) { module = modules[len]; /* */ if (!module[0]) { loader(len); } } } /* - */ function loader (i) { var module = modules[i]; /* script */

, -- - , . , JavaScript-. , « -- »: , , . 70

habradigest 7 · 2009

JAVASCRIT

: DOM-

, , JSX, DOM. , - , jsxcmpet, . DOM-, , , . . , ? ? JSX DOM- . : . , . , . JSX : ( ), , . ?

, dm laded, (e eval) , title ( spa). 3. 3 : yass.dm.js, yass.base.js yass.utils. js. ( , dm base, utils) ( ). : ( ) ( utils-base-dm). 4. - , - (, base-callbacks), «» base callbacks. ( , base) :

_.load('callbacks-base');

5. DOM-: yassmdule-callbacks-base. . :

dom -> base -> utils -> callbacks

: JSX + YASS

. JSX , . , . HTML-:

<div id=»item1» class=»yass-module-utils-base-dom»> <span id=»item2» class=»yass-module-dom» title=»_('#item2')[0].innerHTML = 'component is loading...';»></span> </div>

, . : , . , YASS. .

, : 1. YASS DOM- yassmdule-*. 2. 2 : utils-base-dm dm. , , : habradigest 7 · 2009 71

RUBY

Ruby !

MaxElc

, -- . , ! ?

, ...

Ruby? -- - . -- , . H C++ -- H , -, . C++ , , , , , , , -- . , , -, , ( , Ruby ). Ruby Rails? : « ». ? Rails -- Ruby. «» Ruby ( H), , , , MVC (Mdel -- View -- Ctrller) -- , , .

-- - -- MVC Rails -- -- -- Ope Surce -- , Rails ,

, ;) , , IDE , - . , , , , . : Ruby i Steel Micrsft Visual Studi 2005/2008. , , Widws. , -, IDE, , - Java, ( , ), -, trial 60 , , , . , etBeas IDE 6.0 Ruby. , Ruby i Steel -- , All-i-Oe Istaller -- Visual Studi 2008 . Setup. ( ), Istall ext Fiis . Rails, , «ress ay key t ctiue...». MySQL Widws . 72

Ruby Rails

Ruby Ruby Rails , . : DRY (D't repeat yurself). , . : CC (Cvetis ver Cfigurati) -- . , , , , . , , , .

Ruby?

-- habradigest 7 · 2009

RUBY

-- Visual Studi.

#{cde}.

puts «#{«Ruby! «*4}»

Ruby i Steel VS: File -- ew -- rject -- Ruby I Steel () -- Ruby rject () -- ame ( ) -- OK. -- (rject) , Sluti () . rubyfile.rb, . . rubyfile.rb -- .

«» Kaiser Ciefs ;) !

puts «\n\t#{(1 + 2) * 3}\nGoodbye»

,

(expressi) , , , , - . :

8 2 + «a» 100 x + 3 + «b» + «c» - 5 * (2 - 1) y

Hell Wrld:

puts «Hello World!»

, ... Ctrl+F5 -- , , !

:

x = 5 y = x * 20 x += y puts x

puts «Hello World!\nPrivet Mir!»

(Escape Sequeces), .. \ ( ), \t (), \s () .

puts 'Hello World!\nPrivet Mir!'

, «» -- ES, . , ES , .

puts 'It\'s Ruby'

x 5, y x * 20 (100). y x . , . x = x + y, -- Ruby. x *= y x /=, x += 1 .

:

age = 22 puts «Sovsem Molodoi!» if age < 25

, «» \' .

print «Hello World!» print «Hello World!»

puts prit .

puts «2 x 2 = #{2*2}»

( ), . . . age < 25 -- «/» ( ==, >=, <=, <=>, !=) . : if. te, ed? , :

if age < 25 then puts «Sovsem Molodoi!» end

Ruby -- -- Ruby habradigest 7 · 2009

73

RUBY

. uless:

age = 24 puts «You're NOT a teenager» unless age > 12 && age < 20

, , :

x = 10 y = 3 puts x.to_f / y.to_f

. .

:

4.times do puts «Ruby» end

(.. ) .t_f, . ( ) .t_i.

, . -- , -- . ! C++ Java, , . Ruby, , , . , , , , . , , . . , , . . -- - . -- , «» : . ( ) . , , , (, , , . .) (, , .) -- , «», . . , , -- . 4.times {puts «Ruby»} 4 -- , Iteger ( , ), times, ( , ). , x = 1 + x -- , + -- ! , , , , «» - 74

-- puts. . 4, times, (? ? -- ). , , , d ed. times 4 . , , . , d ed:

4.times { puts «Ruby» }

( ) -- , - . , , . , :

1.upto(5) { ... ... } 10.downto(5) { ... ... } 0.step(50, 5) { ... ... }

, . :

1.upto(5) { |number| puts number }

« » -- . « 1 5» umber.

, , -- ( ). : puts 10 / 3. -- 3. , . , . : puts 10.0 / 3.0. ! habradigest 7 · 2009

RUBY

.

, ,

, Ruby, , , . -- . , , . . :

class Dog def set_name( aName ) @myname = aName end end

class Dog def set_name( aName ) @myname = aName end def get_name return @myname end def gav return 'r-r-r-r!' end end dog1 = Dog.new dog1.set_name( 'Fido' ) puts(dog1.get_name) puts(dog1.gav)

-- ? ;) . class , . set_ame (def...ed), -. aame @myame. , @, -- . , , . ( ) ew:

moya = Dog.new tvoya = Dog.new

, (, ), ( ) («», , ). , -. , , . ... .

-- .

class Cat attr_accessor :name, :age, :gender, :color end class Dog attr_accessor :name, :age, :gender, :color end class Snake attr_accessor :name, :age, :gender, :color, :length end

: , -- . set_ame, :

moya.set_name( 'Lassie' ) tvoya.set_name( 'Rex' )

? «» @ame , (. ). : ; . , :

def get_name return @myname end

. Cat. , , -- . _accessr « ». :

cat_object = Cat.new cat_object.name = «Pussy» ........................ puts cat_object.name

retur , , -- . ( ) :

, , . . Ruby 75

habradigest 7 · 2009

RUBY

. : DRY (D't repeat yurself), , , . : . . , , -- (pets). et, «» , , , ? :

class Pet attr_accessor :name, :age, :gender, :color end class Cat < Pet end class Dog < Pet end class Snake < Pet attr_accessor :length end

. : ( , ). :

a = Array.[](1,2,3,4) b = Array[1,2,3,4] c = [1,2,3,4]

[]. ew, 0, 1 : -- , -- . :

d = Array.new # e = Array.new(3) # [nil, nil, nil] f = Array.new(3, «ruby») # [«ruby», «ruby», «ruby»]

-- , . , , . ( -- {}):

f[0].capitalize! # f : [«Ruby», «Ruby», «Ruby»] g = Array.new(3) { «ruby» } # [«ruby», «ruby», «ruby»] g[0].capitalize! # g : [«Ruby», «ruby», «ruby»]

, , , , . , .

«» , , , : A Z, 1 25. , . :

digits = 0..9 scale1 = 0..10 scale2 = 0...10 #digits = scale2

[] []= . ( ) . -1. at -- , delete_at . :

a b c d e f g h i j = = = = = = = = = = [1, 2, 3, 4, 5, 6] a[0] # 1 a.at(0) # 1 a[-2] # 5 a.at(-2) # 5 a[9] # nil a.at(9) # nil a[3,3] # [4, 5, 6] a[2..4] # [3, 4, 5] a[2...4] # [3, 4]

.. , ... -- ( -- , ). .

. , .. , . . : ( ) . , habradigest 7 · 2009

a[1] = 8 # [1, 8, 3, 4, 5, 6] a[1,3] = [10, 20, 30] # [1, 10, 20, 30, 5, 6] a[0..3] = [2, 4, 6, 8] # [2, 4, 6, 8, 5, 6] a[-1] = 12 # [2, 4, 6, 8, 5, 12] a.delete_at(3) # [1, 2, 4, 5, 6] a.delete_at(9) # nil

-- (pusig) . ji «» , :

x = [] x << «Word»

76

RUBY

x << «Play» << «Fun» puts x.join(', ') # Word, Play, Fun

eac -- , , :

[1, «test», 2, 3, 4].each { |element| puts element.to_s + «X» }

first last , values_at -- , :

x = [«alpha», «beta», «gamma», «delta», «epsilon»] a = x.first # alpha b = x.values_at(0..2,4) # [alpha, beta, gamma, epsilon]

cllect:

[1, 2, 3, 4].collect { |element| element * 2 } #[2, 4, 6, 8]

legt size , items (il), cmpact il :

y c e d = = = = [1, 2, nil, nil, 3, 4] y.size # 6 y.nitems # 4 y.compact # [1, 2, 3, 4]

:

x = [1, 2, 3] y = [«a», «b», «c»] z = x + y #[1, 2, 3, «a», «b», «c»] a = [1, 2, 3, 4] b = [3, 4, 5, 6] a -- b # [1, 2] -- a & b # [3, 4] -- a | b # [1, 2, 3, 4, 5, 6] -- a*2 # [1, 2, 3, 4, 1, 2, 3, 4] -

-- srt ( ). , , -- . , ( t_s):

a = [1, 2, «three», «four», 5, 6] b = a.sort {|x,y| x.to_s <=> y.to_s} # b [1, 2, 5, 6, «four», «three»]

:

: , , . sca split. .

? <=> -- (. ). -1, ( ), , 1 -- ( ). ({|x,y| y.t_s <=> x.t_s}). , . detect (fid -- ) fid_all (select -- ), :

x = [5, 8, 12, 9, 4, 30] # find , x.find {|e| e % 6 == 0 } # 12 # select x.select {|e| e % 6 == 0} # [12, 30]

, : -- -- -- -- -- -- --

reject select -- , :

x = [5, 8, 12, 9, 4, 30] d = c.reject {|e| e % 2 == 0} # [5, 9]

. : -- , , . -- , . -- 77

delete , :

c = [«alpha», «beta», «gamma», «delta»] c.delete(«delta») # = [«alpha», «beta», «gamma»]

habradigest 7 · 2009

RUBY

. -- . -- , . -- , -- , . -- , . , aalyzer.rb.

end puts «#{line_count} lines»

, text . , text . , File , . , :

lines = File.readlines(«text.txt») line_count = lines.size text = lines.join puts «#{line_count} lines»

-

, , . , . text.txt , aalyzer.rb.

! readlies , .

! -- . File. , text.txt:

File.open(«text.txt»).each { |line| puts line }

text, legt, ( ) , , , . :

total_characters = text.length puts «#{total_characters} characters»

aalyzer.rb . . File text.txt, , , eac , , puts . , :

line_count = 0 File.open(«text.txt»).each { |line| line_count += 1 } puts line_count

, -- . . :

puts «foobar».sub('bar', 'foo') #foofoo

lie_cut, , , lie_cut 1 . ( 127 ). ! , - , , . . text, :

text='' line_count = 0 File.open(«text.txt»).each do |line| line_count += 1 text << line

sub , , . sub , , gsub .

? (regular expressi). , . (/patter/). , , . , , , erl yt: /erl|yt/. , , (, pipe, |). « , , , ». , 78

habradigest 7 · 2009

RUBY

: /(erl|yt)/. : /ab+c/ ( , a, b+, ). , a, b, , , . , /ab*c/ a, b . + * -- , , , , . -- , , \s witespace ( , , . .), \d , . , Wikibks:

word_count = text.split.length puts «#{word_count} words»

, , . , . , , -- . :

paragraph_count = text.split(/\n\n/).length puts «#{paragraph_count} paragraphs» sentence_count = text.split(/\.|\?|!/).length puts «#{sentence_count} sentences»

, . . , . . ? -- «» .

, wrd_cut, paragrap_cut setece_cut , :

puts «#{sentence_count / paragraph_count} sentences per paragraph (average)» puts «#{word_count / sentence_count} words per sentence (average)»

, :

total_characters_nospaces = text.gsub(/\s+/, '').length puts «#{total_characters_nospaces} characters excluding spaces»

, . . :

lines = File.readlines(«text.txt») line_count = lines.size text = lines.join word_count = text.split.length character_count = text.length character_count_nospaces = text.gsub(/\s+/, '').length paragraph_count = text.split(/\n\n/).length sentence_count = text.split(/\.|\?|!/).length puts «#{line_count} lines» puts «#{character_count} characters» puts «#{character_count_nospaces} characters excluding spaces» puts «#{word_count} words» puts «#{paragraph_count} paragraphs» puts «#{sentence_count} sentences» puts «#{sentence_count / paragraph_count} sentences per paragraph (average)» puts «#{word_count / sentence_count} words per sentence (average)»

.

: 1. , sca 2. split size. . ( ) split . . :

habradigest 7 · 2009

79

RUBY

inspect

puts «What is your name?» STDOUT.flush chompname = gets.chomp puts «Again, what is your name?» name = gets puts «Hello, « + name puts «Hi, « + chompname puts 'But name = ' + name.inspect + ' and chompname = ' + chompname.inspect

, . .

if a = 7 if a == 4 a = 9 end

STDOUT -- , . flus / . , . , . gets . cmp -- Strig. , , , gets \, cmp \ ( \r \r\). ispect, «» , -- .

, . :

a = 7 a = 9 if a == 4

if-elsif-else

:

a = 7 if a == 4 a = 9 else if a == 7 a = 10 end end

, , , ( «» ). strip :

string = 'Bring, bring a = string.strip! puts string puts a '

elsif :

a = 7 if a == 4 a = 9 elsif a == 7 a = 10 end

, , true false, , empty? true, :

a = [] puts «empty» if a.empty?

a = 7 plus_minus = '+' print «#{a} #{plus_minus} 2 = « + (plus_minus == '+' ? (a+2).to_s : (a-2).to_s)

ay? true, , zer?, umeric, il, , , , .

%w

, : %w{} , :

pets1 = [ 'cat', 'dog', 'snake', 'hamster', 'rat' ] pets2 = %w{ cat dog snake hamster rat } # pets1 = pets2

[? (expr) : (expr)] (terary) ( ) . , . ?, false il, , -- ( :).

while

wile if wile : 80

habradigest 7 · 2009

RUBY

a = 0 while a < 5 puts a.to_s a += 1 end

new initialize

:

class Dog def set_name( aName ) @myname = aName end def get_name return @myname end def gav return 'r-r-r-r!' end end dog1 = Dog.new dog1.set_name( 'Fido' ) puts(dog1.get_name) puts(dog1.gav)

: <......> wile <>

(Symbols)

Symbl , :, , :acti. Symbl -- , -- ID. Symbl' , , , -- symbl , -- :

ruby_know = :yes if ruby_know == :yes puts «You're a good guy!» else puts 'Learn Ruby!' end

:

class Dog def initialize(name, age) @name = name @age = age end def get_name return @name end def get_age return @age end end d = Dog.new('Fido', 2) puts «My name is #{d.get_name} and I'm #{d.get_age}»

:yes -- symbl, , . :yes «yes», , . Kae « ».

( , ases) , . , . :

h = {'dog' => 'sobaka', 'cat' => 'koshka', 'donkey' => 'oslik'} puts h.length puts h['dog'] puts h # 3 # 'sobaka' # catkoshkadonkeyoslikdogsobaka

, , .. , , symbl:

users = Hash.new users[:nickname] = 'MaxElc' users[:language] = 'Russian' puts users[:nickname] #MaxElc

( class ame ... ed), Class. ame.ew , ew Class, allcate, , iitialize . . iitialize, -- ew. iitialize -- (, , -- ). iitialize , set_ame. iitialize 81

habradigest 7 · 2009

RUBY

. ( ew iitialize), (il).

(get_ame get_ age), . , : attr_reader :

class Dog attr_reader :name, :age def initialize(name, age) @name = name @age = age end end d = Dog.new(«Fido», 2) puts «My name is #{d.name} and I'm #{d.age}»

class Snake < Pet def initialize(name, age, length) @name = name @age = age @length = length super(name, age) end def get_length return @length end end d = Dog.new('Fido', 2) s = Snake.new('Lili', 2, 85) puts «Dog: My name is #{d.get_name} and I'm #{d.get_ age}» puts «Snake: My name is #{s.get_name}, I'm #{s.get_age} & I'm #{s.get_length} cm»

, attr_reader symbl' (. ) , . attr_writer set- (set_ame , ), attr_ accessr (. ).

:) . -- super. , . super , super() -- . -, .

initialize +

«», attr_ accessr. , iitialize ? :

class Pet def initialize(name, age) @name = name @age = age end def get_name return @name end def get_age return @age end end class Dog < Pet def initialize(name, age) @name = name @age = age super end end

, «» . : puts d.metds.srt, d -- . bject_id ( , ), class ( , ) istace_f? ( true, , , puts 10.istace_f?(Fixum)) , , respd_t?. :

if d.respond_to?(«gav») d.gav else puts «Sorry, don't understand.» end

Proc

(d ... ed {...}) , rc lambda. call rc. prc':

def method proc puts 'Start of method' proc.call

habradigest 7 · 2009

82

RUBY

puts 'End of method' end say = lambda {puts 'Hello'} method say

freeze Object , . «» , TypeErrr. frze? , :

a = b = 'Original String' b.freeze puts a.frozen? # true puts b.frozen? # true a = 'New String' puts a puts b puts a.frozen? # false puts b.frozen? # true

. , mdule class. , . . ­ , . ( Mdule -- Object, ). . -, , :

module Trig PI = 3.1416 # def Trig.sin(x) # ... end def Trig.cos(x) # ... end end

a b , true . . , , . , .

-, , (iclude) , . (mixi):

module MyModule GOODMOOD = «happy» BADMOOD = «grumpy» def greet return «I'm #{GOODMOOD}. How are you?» end def MyModule.greet return «I'm #{BADMOOD}. How are you?» end end class MyClass include MyModule def sayHi puts( greet ) end end ob = MyClass.new ob.sayHi puts(ob.greet)

Java , . (marsalig), Marsal. ­ dump lad:

f = File.open( 'peoples.sav', 'w' ) Marshal.dump( [«bred», «bert», «kate»], f ) f.close File.open( 'peoples2.sav', 'w' ){ |friendsfile| Marshal.dump( [«anny», «agnes», «john» ], friendsfile ) } myfriends = Marshal.load(File.open('peoples.sav' )) morefriends = Marshal.load(File.open('peoples2.sav' )) puts myfriends puts morefriends

Marsal, YAML , .

( ++) , mixi'.

, , , habradigest 7 · 2009

? , 83

RUBY

. , : , , . , " " (, ):

class SuperCat end def initialize(height, weight, tail_color, head_ color, legs_color) @height, @weight, @tail_color, @head_color, @ legs_color = height, weight, tail_color, head_color, legs_color end def SuperCat.white_cat(height, weight) new(height, weight, «white», «white», «white») end def SuperCat.black_cat(height, weight) new(height, weight, «black», «black», «black») end def SuperCat.big_cat(tail_color, head_color, legs_ color) new(100, 100, tail_color, head_color, legs_ color) end end a = SuperCat.new(10, 15, «white», «black», «white») b = SuperCat.black_cat(13, 20) c = SuperCat.big_cat(«white», «red», «red») p(a); p(b); p(c)

self.name = «Pussy» self.height = 10 self.weight = 12 self.age = 3.2 self.tail_color = «gray» self.head_color = «gray» self.legs_color = «white»

p pussy

, . self, .

, , . , , , , . private Mdule. private . private , . private:

class Bank def open_safe # ... end def close_safe # ... end private :open_safe, :close_safe def make_withdrawal(amount) if access_allowed open_safe get_cash(amount) close_safe end end # - private def get_cash # ... end def access_allowed # ... end end

""? .

, , . , . ­ iitialize. . istace_eval eval:

class HyperCat attr_accessor :name, :height, :weight, :age, :tail_color, :head_color, :legs_color def initialize(&block) instance_eval &block end # ... end pussy = HyperCat.new do

habradigest 7 · 2009

84

RUBY

cle dup . dup , cle , , :

s1 = «cat» def s1.upcase «CaT» end s1_dup = s1.dup s1_clone = s1.clone s1 #=> «cat» s1_dup.upcase #=> «CAT» ( ) s1_clone.upcase #=> «CaT»

def initialize(name, age, weight) @name, @age, @weight = name, age, weight end end lucky = ExtraCat.new(«Lucky», 2, 4)

, , , . Struct. attr_ accessr , Struct , . (structure templates).

ExtraCat = Struct.new(«ExtraCat», :name, :age, :weight) lucky = ExtraCat.new(«Lucky», 2, 4)

, , , , . ? , , . :

module MyMod def meth puts « » puts « .» end end class MyClass class << self # self MyClass include MyMod end end

, . , , . , , bject.respd_t?(«x»): ", , ? . , , def class. .

self

­ , self. self, . , , : (tp level), , . , - . , .rb x=1, .

def m end

exted ­ :

class MyClass extend MyMod end MyClass.meth

Struct'

. :

class ExtraCat attr_accessor :name, :age, :weight

. (start up) self , , mai. mai ­ , self . self ­ , :

class C puts «Started class C:»

habradigest 7 · 2009

85

RUBY

puts self # C module M puts «Module C::M:» puts self # C::M end puts «Back C:» puts self # C end

, CSV , , . CSV, . CVS read CSV - :

require `csv' a=CSV.read(`db.txt') puts a.inspect puts a[0][0] # Fred Bloggs puts a[1][0] # Laura Smith puts a[2][0] # Debbie Watts a[1][1] = "Marine" p(a[1]) # ["Laura Smith", "Marine", "Female", "23"]

self , . def/ed, . , self . self:

, , CSV , csv :

CSV.open(`bd.txt', `w') do |csv| a.each do |a| csv << a end end

, : , , ( ), . . , - . ­ - , , , . . ­ . - (.. ) . ( ), . , . , , , . C++, Java . . SaveAs . , , , , . 86

.txt

. , . , , . ­ . , , , , . , . , CSV (Cmma-Separated Values), , . db.txt, CSV, , :

Fred Bloggs,Manager,Male,45 Laura Smith,Cook,Female,23 Debbie Watts,Professor,Female,38

. cvs, habradigest 7 · 2009

RUBY

:

text = editor() location = ask_user() begin File.open(location, w) do |file| save_work(file, text) end rescue puts " . : #{$!}" end

- , , . , begi rescue . , rescue ed. $! . , , rescue. , , rescue IOErrr. , , ( ) :

rescue IOError puts -- $!. rescue SystemCallError puts -- $!. end

habradigest 7 · 2009

87

RUBY

DSL Ruby

iv_s

Ruby Domain Specific Languages(DSL). DSL, , . , C++ Java, DSL , .

DSL Ruby. Rails DSL . , Ruby DSL . :

: 2.2 : 1 : 250

2

? , . . , . !

comp = Computer.new comp.cpu = 2.2.ghz comp.ram = 2.gb comp.disk = 1.gb

Ruby DSL .

gz gb umeric:

class Numeric def ghz self*1000 end def gb self*1024 end def mhz self end def mb self end end

1

Ruby , ( ):

comp = Computer.new comp.cpu = 2.2 * 1024 comp.ram = 2 * 1024 comp.disk = 1 * 1024

:

class Computer attr_accessor :cpu attr_accessor :ram attr_accessor :disk end

mz mb, cpu.ram = 512. mb cpu.ram = 512. Ruby (mixi) . .. . , .

class String def cool self + « is cool!» end end

Ruby ( @) , .. . , :

def cpu @cpu end def cpu= val @cpu = val end

, : attr_accessr :cpu,

cl self -- , ,

puts «my string».cool

habradigest 7 · 2009

88

RUBY

«My strig is cl!» gz umeric, Ruby.

3

. , «cmp.». -:

comp = Computer.new do cpu 2.2.ghz ram 2.gb disk 1.gb end

# , .. #(a attr_accessor ) # attr :cpu_clock attr :ram_size attr :disk_size end

? . , ( ) . Cmputer cpu , . .

4

, . , BIOS'a :

comp = Computer.new do bios 0.5.mb bus 100 end

, ? ? . , Ruby . cpu, ram disk , , Cmputer. :

def cpu val comp.cpu = val end

cmp? cpu 2.gz, cmp? . ... ! Ruby c istace_eval. Cmputer

class Computer # initialize def initialize &block #&block instance_eval &block # instance_eval end # , cpu= 2.ghz cpu 2.ghz def cpu val @cpu_clock = val end def ram val @ram_size = val end def disk val @disk_size = val end # , cpu # attr attr_accessor,

, . Ruby, metd_missig. metd_missig - , . :

class Test def method_missing name, *args, &block #name - , *args - , &block - . puts name.to_s + « called» end end t = Test.new t.some_method # «some_method called» t.asdf #»asdf called»

Cmputer:

class Computer def initialize &block instance_eval &block end def method_missing name, *args, &block instance_variable_set(«@#{name}».to_sym, args[0]) # self.class.send(:define_method, name, proc { instance_variable_get(«@#{name}»)}) # end end

habradigest 7 · 2009

89

RUBY

. . . , metd_missig ame args. , , , . . , metd_missig Rails ActiveRecrd, ers.fid_all_by_ame .

: 2.2 : 1 : 250

. . , DSL XHTML. , , . gem , : -- Widws: gem istall rml -- *ix : sud gem istall rml : ttp://rubyfrge.rg/prjects/rml/. : ttp://rml.rubyfrge.rg/.

, DSL ? DSL , , , . . my_pc.cf:

cpu 1.8.mgh ram 512.mb disk 40.gb

, , istace_eval . -, , :

comp = Computer.new do 2.2.ghz 2.gb 1.gb end

, -Ku . :

ruby -Ku test.rb

DSL, Ruby . . . cpu 1.gz cpu 1gz. . , . , , , : habradigest 7 · 2009 90

RUBY

Ruby,

Kane,

21 Ruby. , . «» Ruby -- irb. Ruby, . , .

1.

, matc. :

email = «Fred Bloggs <[email protected]>» email.match(/<(.*?)>/)[1] # => com» email[/<(.*?)>/, 1] # => com» email.match(/(x)/)[1] # => [:(] email[/(x)/, 1] # => email[/([bcd]).*?([fgh])/, 2] # => «[email protected] «[email protected] NoMethodError nil «g»

4.

, :

«[%s]» % «same old drag» # => «[same old drag]»

:

x = %w{p hello p} «<%s>%s</%s>» % x # => «<p>hello</p>»

5.

-, bas, fileutils: require 'fileutils' FileUtils.rm_r 'smedir'

, . :

name, mail = *email.match(/(.+)\s<(.*)>/)[1..2] puts name # «Fred Bloggs» puts mail # «[email protected]»

6.

«*» «» ( ). , :

a = %w{a b} b = %w{c d} [a + b] [*a + b]

2. Array#join

, Array#* «» , . , , «» , Array#ji:

%w{this is a test} * «, « # => «this, is, a, test» h = { :name => «Fred», :age => 77 } h.map { |i| i * «=» } * «\n» # => «age=77\nname=Fred»

# => [[«a», «b», «c», «d»]] # => [«a», «b», «c», «d»]

a = { :name => «Fred», :age => 93 } [a] # => [{:name => «Fred», :age =>93}] [*a] # => [[:name, «Fred»], [:age, 93]] a = %w{a b c d e f g h} b = [0, 5, 6] a.values_at(*b).inspect

3. .

, , , spritf, , Ruby :

money = 9.5 «%.2f» % money # => «9.50»

# => [«a», «f», «g»]

:

fruit = [«apple»,»red»,»banana»,»yellow»] # [«apple», «red», «banana», «yellow»] Hash[*fruit] # {«apple»=>»red», «banana»=>»yellow»}

7. .

-, 91

habradigest 7 · 2009

, , « ». - . , , :

(z ||= []) << 'test'

when 1970..1979: «» when 1980..1989: «» when 1990..1999: «» end

13.

%w{rubygems daemons eventmachine}.each { |x| require x }

8.

, :

does = is = { true => 'Yes', false => 'No' } does[10 == 50] # => «No» is[10 > 5] # => «Yes»

14.

, - . -- , :

puts x == 10 ? «x » : «x » # , : LOG.sev_threshold = ENVIRONMENT == :development ? Logger::DEBUG : Logger::INFO

9. and or

, :

queue = [] %w{hello x world}.each do |word| queue << word and puts «Added to queue» unless word. length < 2 end puts queue.inspect # Output: # Added to queue # Added to queue # [«hello», «world»]

15.

, , :

qty = 1 qty == 0 ? 'none' : qty == 1 ? 'one' : 'many'

, ... :

(qty == 0 ? 'none' : (qty == 1 ? 'one' : 'many'))

10. ,

, . , require:

if __FILE__ == $0 # , end

16.

- :

def odd?(x) if x % 2 == 0 return false else return true end end

11.

:

a, b, c, d = 1, 2, 3, 4

! :

def odd?(x) # , return x % 2 == 0 ? false : true end

12.

if x > 1000 && x < 2000, :

year = 1972 puts case year

, , , «==» true false:

def odd?(x) x % 2 != 0 end

habradigest 7 · 2009

92

17. backtrace

def do_division_by_zero; 5 / 0; end begin do_division_by_zero rescue => exception puts exception.backtrace end

22. , -

, . :

def foo(a, b=(flag=true; 666)) puts «b #{b}, flag #{flag.inspect}» end foo 100 # b 666, flag true foo 100, 666 # b 666, flag nil foo 100, 400 # b 400, flag nil

18. ,

[*items].each do |item| # ... end

, items -- , , «[]», , , «[]» «*» -.

23. 10 2 36

1234567890.to_s(2) 1234567890.to_s(8) 1234567890.to_s(16) 1234567890.to_s(24) 1234567890.to_s(36) # # # # # «1001001100101100000001011010010» «11145401322» «499602d2» «6b1230i» «kf12oi»

19. rescue begin

def x begin # ... rescue # ... end end

def x # ... rescue # ... end

20.

«#», :

puts «x» =begin this is a block comment You can put anything you like here! puts «y» =end puts «z»

21. Rescue

rescue :

h = { :age => 10 } h[:name].downcase h[:name].downcase rescue «No name» name» # ERROR # => «No

habradigest 7 · 2009

93

RUBY

Ruby on Rails

MaxElc

Ruby on Rails ( ). , . , .

Ruby Rails ( RR)? ­ Ruby ( ) , ( ) MVC. : -- Ruby -- MVC .

1

RoR ­

­ , , , , . , RR, 2004 . , - , ORM RR Active Recrd. , RR (scema) . .

Acti ack. , , .

Active Record

Active Recrd ­ RR. . Active Recrd ORM . ORM Object-relatial mappig (- ). Active Recrd : -- . cveti ver cfigurati ( ). ­ , ­ . . , , ORM , . -- . , AI, Active Recrd, . Active Recrd MySQL, stgres, MS SQLServer, DB2, SQLite. database.yml. -- CRUD. create (), retrieve (), update () delete () . Active Recrd ­ ORM , . , . , Active Recrd . -- . 94

RoR MVC

, MVC , MVC RR? MVC ­ , : -- Mdel ( ) «» , . . -- View (, ) , . MVC, . -- Ctrller (, ) . , . MVC ( 1). RR : -- Active Recrd -- Acti View -- Acti Ctrller habradigest 7 · 2009

RUBY

­ . Active Recrd . , , , .

: (develpmet), (testig) (prducti), . . -- development. ­ . . , . -- test. - , , . - RR . , . -- production. , . , . . ­ prducti.

Action View

, . RR Acti View. Acti View: -- (Templates). ­ , (placelders), . HTML- Ruby, HTML (embedded) Ruby (ERb). -- (elper, ) . , , , . , , . -- . (layuts) , . , , AI .

Instant Rails

Widws , - , RR Istat Rails. : -- Ruby, -- SQLite MySQL, -- - Apace (, , ...) -- Rails Istat Rails (IR) , (, , , C:\ ruby). 18000 , . IstatRails. exe , ­ ­ -, , SQLite. , , , . , , , , . , RR ­ . ? gem.

Action Controller

- . , , - , . RR Acti Ctrller , : -- . ­ , . ckie . Ckie ­ , , . -- . , , , , , , . , Acti Ctrller. : befre, after arud. ­ . -- . ­ , , .

RR habradigest 7 · 2009

95

RUBY

gem

, Ruby Applicati Arcive (RAA), 1700 . ( , ) gem. (-> ->> cmd->OK). IR (cd c:/ruby) use_ruby (use_ruby.bat) ­ bat ATH, RR , RR . use_ruby.bat, . : gem list «». gem update , , , . ( , , ): -- gem istall rubygems-update -- update_rubygems -- gem uistall rails activerecrd activeresurce activesupprt actipack actimailer -- gem istall rails --iclude-depedecies , , , , . , ( , ).

RR rails, . - « », rails_apps ( ). test, : rails test. . , , . , , - Mgrel, . (cd test) : ruby script/server. Mgrel:

, 3000 . ,

http://127.0.0.1:3000/

« »

MySQL, . , Ruby Ruby 1.8.6 Oe-Click Istaller -- Widws, . -- Ruby-186-xx -- Ruby Gems -- Ruby Gems package maager , , (rails --iclude-depedecies, mysql, mgrel).

­ . , ;) "Abut yur applicati's evirmet", :

, RR . ­ RR . :

­ , RR . habradigest 7 · 2009

«dem» . -- RR, , -, REST . 96

RUBY

, RR , , : -- app: ctrllers: elpers: mdels: , views: layuts: -- cfig: , evirmets: , iitializers: , -- db: Active Recrd -- dc: - -- lib: , -- lg: -- public: styleseets: CSS javascripts: JavaScript images: -- script: Sell- RR -- test: fixtures: , fuctial: itegrati: uit: - -- tmp: Rais -- vedr: , plugis: RR "Hell Wrld" . , , . , RR : , . ­ , HTML-. , HTML , RR , . - RR, ( , ) . :

ruby script/generate controller Hi index

: ctrller , , Hi ­ . idex idex, , , . , :

exists exists create exists create create create create app/controllers/ app/helpers/ app/views/hi test/functional/ app/controllers/hi_controller.rb test/functional/hi_controller_test.rb app/helpers/hi_helper.rb app/views/hi/index.html.erb

, exists, , , . , , : i , , , idex.tml.erb ( .tml.erb ­ HTML ). idex .

http://127.0.0.1:3000/hi/:

, , app/views/i/idex.tml.erb. , , HTML. :

<html> <head><title>Hi Habrahabr!</title></head> <body> <h1>Hello!</h1> <p> app/views/hi/index.html. erb</p> </body> </html>

:

script/geerate ­ Sell- geerate script, , ( ruby ). habradigest 7 · 2009 97

RUBY

, , HTML . , RR, app/ctrllers/i_ctrller.rb. , :

class HiController < ApplicationController def index end end

5.times do puts «<p> #{@message} </p>» # , end

.erb, :

<% 5.times do%> <p><%= @message %></p> <% end %>

, : HiCtrller (, -- CC ), ApplicatiCtrller idex. , . RR ( , @):

class HiController < ApplicationController def index @habr = `Habrahabr' @message = ` ' end end

puts <%= ... %>. = . .

, :

<html> <head><title>Hi <%= @habr %>!</title></head> <body> <h1>Hello!</h1> <p> app/views/hi/index.html. erb</p> <p><%= @message %></p> </body> </html>

?

, RR 127.0.0.1:3000/i/ Hi. RR , -- , -- . , idex, . . RR . , ? cvetis -- .

, HTML. HTML- <%= ... %> ­ (expressi). , Time.w. HTML <%= Time.w %>, MVC . "" .

, , , . -- , . !

, , , . , @message . , : habradigest 7 · 2009 98

web , , . , .

Widws Liux Macits Ukw BSD Symbia OS Su Slaris Ukw Uix system OS/2 84.87% 10.09% 4.54% 0.32% 0.12% <0.1 % <0.1 % <0.1 % <0.1 %

Russia Ukraie Belarus Kazaksta Germay (t set) Uited States Latvia Mldva Estia 63.43% 20.74% 5.86% 1.83% 1.13% 0.88% 0.76% 0.76% 0.69% 0.63%

Firefx Opera Crme MS Iteret Explrer 56.12% 23.9% 11.16% 5.49%

, : adrianopol, Kotter, MaxElc, iv-s, alek-sys, Kane, depp, sunnybear, RollingStone, kmike, uj2, Skaizer, Panya, smira, butaji, acerv, stboris .

RSS-readers

Ggle Feedfetcer Opera RSS Reader FeedDeam Widws RSS latfrm Thuderbird etewsWire 70% 12% 4% 4% 1% 1%

habradigest

"XaocCPS" - , , , "OnTheFly" - , , habradigest, 2009

habradigest 7 · 2009

99

Information

101 pages

Report File (DMCA)

Our content is added by our users. We aim to remove reported files within 1 working day. Please use this link to notify us:

Report this file as copyright or inappropriate

628470