1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Embedding Perl in HTML with Mason Chapter 2: Components- P2 doc

21 312 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Chapter 2: Components- P2
Định dạng
Số trang 21
Dung lượng 53,44 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

For example, this filter uppercases all of the component's output: variables declared here remain in existence and in scope until the component is flushed from memory or the Perl interpr

Trang 1

Chapter 2: Components- P2

This example demonstrates all the syntax possibilities for this block First of all, we have argument types and names The valid types are scalar, array, and hash, represented by their corresponding Perl sigil ($, @, or %), exactly

as would be expected

It is possible to give an argument a default value to be used if none is

provided when the component is called Any argument without a default is

considered a required argument Calling a component without specifying all

its required arguments will cause a fatal exception to be thrown

An argument's default can refer to an earlier argument, so this is completely legal:

It is possible to have comments both after an argument declaration and on their own line Comments start with the # character and continue to the end

of the line, just as in Perl Blank lines are also allowed

<%filter> blocks

Trang 2

A <%filter> block is called after a component has finished running It is given the entire output of the component in the $_ variable, and any changes

to this variable are reflected in the output of the component For example, this filter uppercases all of the component's output:

variables declared here remain in existence (and in scope) until the

component is flushed from memory or the Perl interpreter running Mason shuts down, whichever comes first The <%once> section is useful for things like creating database handles or instantiating large, resource-

Trang 3

The cleanup block is executed right before the component exits and is the counterpart to the <%init> block It is useful if you have created resources such as circular references that need to be freed Technically, it is the same as placing a <%perl> block at the end of a component

Since cleanup code tends to be put at the end of the component anyway,

<%cleanup> blocks aren't very common Their chief advantage is that their name is cleanup

Cleanup blocks are not executed if the component dies or aborts

<%text> blocks

The contents of this block are output exactly as they are, without any

parsing This if useful if you need to write a component containing text about Mason For example:

<%text>

Substitution tags look like this: <% $var %>

Trang 4

</%text>

<%doc> blocks

This block is intended for use by component authors for documentation purposes Its contents are completely ignored In the future Mason may do something more useful with them

<%doc>

=head1 My Story

This is the part where I tell you what the

component does But I'd

rather tell you a story about my childhood When

I was but a

child, my mother said to me

</%doc>

As you can see, there's no reason not to use POD (Perl's Plain Old

Documentation markup language) in these blocks, and you can even run perldoc on a component file

<%flags> and <%attr> blocks

These two blocks share the same syntax and are used to declare one or more key/value pairs The key can contain only letters, numbers, and the

underscore character ( _ ) The value can be any Perl expression whose

results can fit into a scalar (such as a number, string, reference, or undef )

Trang 5

As in the <%args> block, the syntax in these blocks looks like Perl, but it is

not First, you cannot end a line with a comma or semicolon Second, the

whole key/value pair must be on a single line

The difference between these two is that the <%flags> block may contain only official Mason flags, which are used to affect the component's

behavior Currently, there is only one flag defined, inherit This is used

to specify the component's parent component Component inheritance is discussed in Chapter 3

The <%attr> block may contain any keys that you want, as the variables defined in this block are not used by Mason but may be used in your code Its contents are available by calling the object's attr() method and giving the desired key as the argument See Chapter 5 for the details

color => "I'm so blue"

size => 'mucho grande'

</%attr>

My color: <% $m->base_comp->attr('color') %>

Trang 6

There is one other important difference between flags and attributes: flags refer to only the current component, whereas attributes are part of Mason's inheritance scheme, discussed in Chapter 5

<%def> and <%method> blocks

These two blocks use a syntax slightly different from any other Mason block because their contents are, in turn, components The <%def> block contains

a subcomponent, an embedded component that can be called via the normal

Mason component calling syntax A <%method> block also contains an embedded component, but one that may be inherited by a component's

children <%def> and <%method> blocks require a name in the initial tag

In the following example, a subcomponent named make_a_link is defined:

Trang 7

The name of a subcomponent or method may contain alphanumerics,

underscores ( _ ), dashes ( - ), or periods ( ) Customarily, a period is the first character of subcomponent names, in order to distinguish them from nonembedded components Methods generally do not follow this

convention; they have names without leading periods

The main difference between subcomponents and methods is simply that subcomponents are visible only within the component in which they are defined, whereas methods are visible outside of the component and can be inherited via Mason's component inheritance mechanism Subcomponents and methods are covered in Chapter 5

<%shared> blocks

This block also contains Perl code Code in this block is executed once per request, before the <%init> block, but unlike in an <%init> block, the variables declared in this block are in scope both in the component's main body and in any subcomponents or methods it may contain This is useful for sharing a common chunk of code between all the parts of a single

component The uses of this block are discussed in Chapter 5

Trang 10

Since we are talking about arguments, it is worth revisiting the <%args> block discussed previously This block is used to declare the arguments that

a component expects In addition, it can also be used to specify a default value if none is given when the component is called

The block we used earlier was:

<%args>

$color

$size => 20

@items => ( 1, 2, 'something else' )

%pairs => ( key1 => 1, key2 => 'value' )

These arguments are all available in your component as lexically scoped variables For example, your component will have a lexically scoped

$color variable available You do not need to declare it anywhere but in the <%args> block

If a mandatory argument (one with no default) is not provided in the call to the component, an exception is thrown If an argument with a default is not given a value, the default is transparently assigned to the variable Just to be

Trang 11

clear, we will explicitly note that undef is a valid value for an argument It

is the absence of an argument that causes the exception

%ARGS

In addition to any lexically scoped variables created via their declaration in

an <%args> block, each component body also has a lexically scoped hash called %ARGS This hash contains all of the arguments with which the

component was called

One point of confusion for those new to Mason is the difference between

%ARGS and the <%args> block The %ARGS hash contains the arguments

exactly as they were passed to a component, whether or not they are

declared in the <%args> block The keys of the %ARGS hash do not contain the Perl sigils ($, @, or %) An argument declared as $color in the

<%args> block would therefore be available via $ARGS{color} Any assignment of defaults by the <%args> block is not visible in %ARGS; the values are given exactly as they were passed

In addition, the %ARGS hash is always present,5 but the <%args> block is optional

If you are expecting input with a large number of similarly named items, such as input1 , input2 , and so on through input20 , declaring all of them in an <%args> block may be a bit unwieldy In this case, the %ARGS hash can be quite handy

%ARGS is also useful if you expect arguments with names that cannot be used for Perl variables For example, when submitting a web form by

clicking on an image named submit , the browser will generate two

Trang 12

additional form values, called submit.x and submit.y You cannot have a Perl variable named $submit.x, so the only way to get at this argument is to check $ARGS{'submit.x'}

There are other ways to retrieve the arguments passed to a component,

which are discussed in Chapter 4

arguments are passed, @_ is always available in components

So the following pieces of code are near-identical when a component

receives an even number of arguments:

% foreach (sort %ARGS) {

Trang 13

Argument Examples

Let's take a look at a number of scenarios involving

argument passing, first via an HTTP URL query string and then via an

internal component call Then we will see how this interacts with the

component's <%args> block and the %ARGS hash

Arguments submitted via POST and GET requests are treated in exactly the same way, and if both are present they are merged together before the

For each example, we show you two ways to call that component The first

is via an HTTP query string, which is how a component is called to generate

a web page The second is via a component call tag, as a component would

be called from another Mason component

• /some/component?colors=blue <& /some/component, colors => 'blue'

&>

In both cases, $colors is the string "blue" and @colors is a

single-element array containing ('blue') In addition,

$ARGS{colors} would be the string "blue" as well

Trang 14

This component will die when it is called, however, because Mason does not allow you to assign an odd number of elements to a hash, so the assignment to %colors is fatal

• /some/component?colors=blue&colors=red&colors=green <&

/some/component, colors => [ 'blue', 'red', 'green' ] &>

Again the URL and internal example give the same result The

$colors variables contains a reference to a three-element array, ['blue','red','green'] This time, $ARGS{colors} contains the same three-element array reference as $colors and the

@colors array contains a three-element array with those same elements

Again, assigning an odd number of elements to the %colors hash causes a fatal error

• /some/component?colors=blue&colors=cyan&colors=green&colors=mint <& /some/component, colors => [ 'blue', 'cyan', 'green', 'mint' ]

&>

Now, $colors contains a reference to a four-element array, and the

@colors array has four elements as well Finally, the assignment to

%colors works without an error and will result in a hash containing ('blue'=>'cyan','green'=>'mint' ) $ARGS{colors}

contains the same array reference as $colors

• <& /some/component, colors => { blue => 'cyan', green => 'mint' }

&>

Trang 15

This set of arguments isn't representable with a query string, because there's no way to indicate that the arguments are structured in a hash via a web request

In this call, $colors contains a reference to a hash, not an array, though the @colors array contains four elements, just as in the previous example The %colors hash is likewise the same as the previous example Now, the $ARGS{colors} hash entry contains a

hash reference

This discrepancy in how hash assignments are treated, depending on the way

a call is made, is probably not too important because Mason simply does the right thing based on the contents of %args You declare %colors as an argument, and as long as an even number of colors elements are passed

in, you get a hash

Arguments via Component Calls

When calling another component that expects named

arguments, it is important to remember that arrays and hashes need to be passed as references For example, a component named /display with an

<%args> block like this:

Trang 16

<& /display, elements => \@some_data, labels =>

\%data_labels &>

Mason will do the right thing and translate the references back into an array and a hash in the /display component

Arguments via HTTP Requests

When using Mason to make a web application, you must understand the details of how external HTTP requests are converted into component calls Specifically, we are interested in how query string and POST parameters are converted into arguments

These requests are expected to be in the standard name/value pair scheme used by most web interfaces If a parameter is given only once (i.e.,

component?foo=1&bar=2), it will be present in the %ARGS hash as a simple scalar, regardless of how it is declared in the <%args> section

If a parameter is declared as a scalar ($foo) but given multiple values (i.e., component?foo=1&foo=2), the $foo parameter will end up containing

a reference to an array, as will $ARGS{foo} Future versions of Mason may provide the ability to coerce these arguments into specific data

structures

If a parameter is declared as an array (@foo), it will contain zero or more values depending on what is in the query string and/or POST data A hash is treated more or less like an array, except that giving a parameter declared as

a hash an odd number of values will cause a fatal error

One caution: the key/value associations in a declared hash are determined by the order of the input Let's assume we have a component with this

<%args> block:

Trang 17

component that may be called via an HTTP request generated by a form When you can control the query string yourself, this is not a problem

Component Return Values

So far, we know three ways to call c omponents: by using the inline

component call tag (<& &>), by using the $m->comp() method, or via a URL When using a component call tag, the called component's output is placed exactly where the tag was When a component is called via a URL, its output is sent to the client The $m->comp() tag offers an additional channel of component output: the return value By default, Mason

components return undef If you want to return something else, you can add an explicit return() statement inside that component, such as this:

<%init>

my $size = 20;

return $size;

Trang 18

This variable is an HTML::Mason::Request object, which has a number

of methods that allow you to do things such as retrieve information on the current request, call other components, or affect the flow of execution This object is discussed in detail in Chapter 4

$r

If Mason is running under mod_perl (as is the case in most Mason setups), all components also have access to the Apache request object via the global variable $r Mason's special hooks into mod_perl are covered in Chapter

7

Sample Component

The component shown in Example 2-1 is part of our sample site and the focus of Chapter 8 The component here is responsible for displaying news about the site It is called news.mas and is not intended to standalone by itself, but rather to form one part of a complete page

Ngày đăng: 14/12/2013, 12:15

TỪ KHÓA LIÊN QUAN